blob: f7323f0d3570a3dcb527f35f4aae895138107e48 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530168static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700169{
170 WLAN_CIPHER_SUITE_WEP40,
171 WLAN_CIPHER_SUITE_WEP104,
172 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800173#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700174#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
175 WLAN_CIPHER_SUITE_KRK,
176 WLAN_CIPHER_SUITE_CCMP,
177#else
178 WLAN_CIPHER_SUITE_CCMP,
179#endif
180#ifdef FEATURE_WLAN_WAPI
181 WLAN_CIPHER_SUITE_SMS4,
182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700183#ifdef WLAN_FEATURE_11W
184 WLAN_CIPHER_SUITE_AES_CMAC,
185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700186};
187
188static inline int is_broadcast_ether_addr(const u8 *addr)
189{
190 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
191 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
192}
193
194static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530195{
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 HDD2GHZCHAN(2412, 1, 0) ,
197 HDD2GHZCHAN(2417, 2, 0) ,
198 HDD2GHZCHAN(2422, 3, 0) ,
199 HDD2GHZCHAN(2427, 4, 0) ,
200 HDD2GHZCHAN(2432, 5, 0) ,
201 HDD2GHZCHAN(2437, 6, 0) ,
202 HDD2GHZCHAN(2442, 7, 0) ,
203 HDD2GHZCHAN(2447, 8, 0) ,
204 HDD2GHZCHAN(2452, 9, 0) ,
205 HDD2GHZCHAN(2457, 10, 0) ,
206 HDD2GHZCHAN(2462, 11, 0) ,
207 HDD2GHZCHAN(2467, 12, 0) ,
208 HDD2GHZCHAN(2472, 13, 0) ,
209 HDD2GHZCHAN(2484, 14, 0) ,
210};
211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
213{
214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2437, 6, 0) ,
216 HDD2GHZCHAN(2462, 11, 0) ,
217};
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219static struct ieee80211_channel hdd_channels_5_GHZ[] =
220{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700221 HDD5GHZCHAN(4920, 240, 0) ,
222 HDD5GHZCHAN(4940, 244, 0) ,
223 HDD5GHZCHAN(4960, 248, 0) ,
224 HDD5GHZCHAN(4980, 252, 0) ,
225 HDD5GHZCHAN(5040, 208, 0) ,
226 HDD5GHZCHAN(5060, 212, 0) ,
227 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5180, 36, 0) ,
229 HDD5GHZCHAN(5200, 40, 0) ,
230 HDD5GHZCHAN(5220, 44, 0) ,
231 HDD5GHZCHAN(5240, 48, 0) ,
232 HDD5GHZCHAN(5260, 52, 0) ,
233 HDD5GHZCHAN(5280, 56, 0) ,
234 HDD5GHZCHAN(5300, 60, 0) ,
235 HDD5GHZCHAN(5320, 64, 0) ,
236 HDD5GHZCHAN(5500,100, 0) ,
237 HDD5GHZCHAN(5520,104, 0) ,
238 HDD5GHZCHAN(5540,108, 0) ,
239 HDD5GHZCHAN(5560,112, 0) ,
240 HDD5GHZCHAN(5580,116, 0) ,
241 HDD5GHZCHAN(5600,120, 0) ,
242 HDD5GHZCHAN(5620,124, 0) ,
243 HDD5GHZCHAN(5640,128, 0) ,
244 HDD5GHZCHAN(5660,132, 0) ,
245 HDD5GHZCHAN(5680,136, 0) ,
246 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800247#ifdef FEATURE_WLAN_CH144
248 HDD5GHZCHAN(5720,144, 0) ,
249#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDD5GHZCHAN(5745,149, 0) ,
251 HDD5GHZCHAN(5765,153, 0) ,
252 HDD5GHZCHAN(5785,157, 0) ,
253 HDD5GHZCHAN(5805,161, 0) ,
254 HDD5GHZCHAN(5825,165, 0) ,
255};
256
257static struct ieee80211_rate g_mode_rates[] =
258{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530259 HDD_G_MODE_RATETAB(10, 0x1, 0),
260 HDD_G_MODE_RATETAB(20, 0x2, 0),
261 HDD_G_MODE_RATETAB(55, 0x4, 0),
262 HDD_G_MODE_RATETAB(110, 0x8, 0),
263 HDD_G_MODE_RATETAB(60, 0x10, 0),
264 HDD_G_MODE_RATETAB(90, 0x20, 0),
265 HDD_G_MODE_RATETAB(120, 0x40, 0),
266 HDD_G_MODE_RATETAB(180, 0x80, 0),
267 HDD_G_MODE_RATETAB(240, 0x100, 0),
268 HDD_G_MODE_RATETAB(360, 0x200, 0),
269 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271};
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273static struct ieee80211_rate a_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
283};
284
285static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
286{
287 .channels = hdd_channels_2_4_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
289 .band = IEEE80211_BAND_2GHZ,
290 .bitrates = g_mode_rates,
291 .n_bitrates = g_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
297 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
298 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
299 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
300 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
301 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
302};
303
Jeff Johnson295189b2012-06-20 16:38:30 -0700304static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
305{
306 .channels = hdd_social_channels_2_4_GHZ,
307 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
308 .band = IEEE80211_BAND_2GHZ,
309 .bitrates = g_mode_rates,
310 .n_bitrates = g_mode_rates_size,
311 .ht_cap.ht_supported = 1,
312 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
313 | IEEE80211_HT_CAP_GRN_FLD
314 | IEEE80211_HT_CAP_DSSSCCK40
315 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
316 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
317 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
318 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
319 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
320 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
321};
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
324{
325 .channels = hdd_channels_5_GHZ,
326 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
327 .band = IEEE80211_BAND_5GHZ,
328 .bitrates = a_mode_rates,
329 .n_bitrates = a_mode_rates_size,
330 .ht_cap.ht_supported = 1,
331 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
332 | IEEE80211_HT_CAP_GRN_FLD
333 | IEEE80211_HT_CAP_DSSSCCK40
334 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
335 | IEEE80211_HT_CAP_SGI_40
336 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
337 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
338 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
339 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
340 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
341 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
342};
343
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530344/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 TX/RX direction for each kind of interface */
346static const struct ieee80211_txrx_stypes
347wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
348 [NL80211_IFTYPE_STATION] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_AP] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700363 [NL80211_IFTYPE_ADHOC] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ) |
368 BIT(SIR_MAC_MGMT_DISASSOC) |
369 BIT(SIR_MAC_MGMT_AUTH) |
370 BIT(SIR_MAC_MGMT_DEAUTH) |
371 BIT(SIR_MAC_MGMT_ACTION),
372 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 [NL80211_IFTYPE_P2P_CLIENT] = {
374 .tx = 0xffff,
375 .rx = BIT(SIR_MAC_MGMT_ACTION) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ),
377 },
378 [NL80211_IFTYPE_P2P_GO] = {
379 /* This is also same as for SoftAP */
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389};
390
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392static const struct ieee80211_iface_limit
393wlan_hdd_iface_limit[] = {
394 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /* max = 3 ; Our driver create two interfaces during driver init
396 * wlan0 and p2p0 interfaces. p2p0 is considered as station
397 * interface until a group is formed. In JB architecture, once the
398 * group is formed, interface type of p2p0 is changed to P2P GO or
399 * Client.
400 * When supplicant remove the group, it first issue a set interface
401 * cmd to change the mode back to Station. In JB this works fine as
402 * we advertize two station type interface during driver init.
403 * Some vendors create separate interface for P2P GO/Client,
404 * after group formation(Third one). But while group remove
405 * supplicant first tries to change the mode(3rd interface) to STATION
406 * But as we advertized only two sta type interfaces nl80211 was
407 * returning error for the third one which was leading to failure in
408 * delete interface. Ideally while removing the group, supplicant
409 * should not try to change the 3rd interface mode to Station type.
410 * Till we get a fix in wpa_supplicant, we advertize max STA
411 * interface type to 3
412 */
413 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .types = BIT(NL80211_IFTYPE_STATION),
415 },
416 {
417 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700418 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 },
420 {
421 .max = 1,
422 .types = BIT(NL80211_IFTYPE_P2P_GO) |
423 BIT(NL80211_IFTYPE_P2P_CLIENT),
424 },
425};
426
427/* By default, only single channel concurrency is allowed */
428static struct ieee80211_iface_combination
429wlan_hdd_iface_combination = {
430 .limits = wlan_hdd_iface_limit,
431 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800432 /*
433 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
434 * and p2p0 interfaces during driver init
435 * Some vendors create separate interface for P2P operations.
436 * wlan0: STA interface
437 * p2p0: P2P Device interface, action frames goes
438 * through this interface.
439 * p2p-xx: P2P interface, After GO negotiation this interface is
440 * created for p2p operations(GO/CLIENT interface).
441 */
442 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800443 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
444 .beacon_int_infra_match = false,
445};
446#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800447
Jeff Johnson295189b2012-06-20 16:38:30 -0700448static struct cfg80211_ops wlan_hdd_cfg80211_ops;
449
450/* Data rate 100KBPS based on IE Index */
451struct index_data_rate_type
452{
453 v_U8_t beacon_rate_index;
454 v_U16_t supported_rate[4];
455};
456
457/* 11B, 11G Rate table include Basic rate and Extended rate
458 The IDX field is the rate index
459 The HI field is the rate when RSSI is strong or being ignored
460 (in this case we report actual rate)
461 The MID field is the rate when RSSI is moderate
462 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
463 The LO field is the rate when RSSI is low
464 (in this case we don't report rates, actual current rate used)
465 */
466static const struct
467{
468 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700470} supported_data_rate[] =
471{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700472/* IDX HI HM LM LO (RSSI-based index */
473 {2, { 10, 10, 10, 0}},
474 {4, { 20, 20, 10, 0}},
475 {11, { 55, 20, 10, 0}},
476 {12, { 60, 55, 20, 0}},
477 {18, { 90, 55, 20, 0}},
478 {22, {110, 55, 20, 0}},
479 {24, {120, 90, 60, 0}},
480 {36, {180, 120, 60, 0}},
481 {44, {220, 180, 60, 0}},
482 {48, {240, 180, 90, 0}},
483 {66, {330, 180, 90, 0}},
484 {72, {360, 240, 90, 0}},
485 {96, {480, 240, 120, 0}},
486 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700487};
488
489/* MCS Based rate table */
490static struct index_data_rate_type supported_mcs_rate[] =
491{
492/* MCS L20 L40 S20 S40 */
493 {0, {65, 135, 72, 150}},
494 {1, {130, 270, 144, 300}},
495 {2, {195, 405, 217, 450}},
496 {3, {260, 540, 289, 600}},
497 {4, {390, 810, 433, 900}},
498 {5, {520, 1080, 578, 1200}},
499 {6, {585, 1215, 650, 1350}},
500 {7, {650, 1350, 722, 1500}}
501};
502
Leo Chang6f8870f2013-03-26 18:11:36 -0700503#ifdef WLAN_FEATURE_11AC
504
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530505#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700506
507struct index_vht_data_rate_type
508{
509 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510 v_U16_t supported_VHT80_rate[2];
511 v_U16_t supported_VHT40_rate[2];
512 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700513};
514
515typedef enum
516{
517 DATA_RATE_11AC_MAX_MCS_7,
518 DATA_RATE_11AC_MAX_MCS_8,
519 DATA_RATE_11AC_MAX_MCS_9,
520 DATA_RATE_11AC_MAX_MCS_NA
521} eDataRate11ACMaxMcs;
522
523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
Jeff Johnson295189b2012-06-20 16:38:30 -0700540extern struct net_device_ops net_ops_struct;
541
Leo Chang9056f462013-08-01 19:21:11 -0700542#ifdef WLAN_NL80211_TESTMODE
543enum wlan_hdd_tm_attr
544{
545 WLAN_HDD_TM_ATTR_INVALID = 0,
546 WLAN_HDD_TM_ATTR_CMD = 1,
547 WLAN_HDD_TM_ATTR_DATA = 2,
548 WLAN_HDD_TM_ATTR_TYPE = 3,
549 /* keep last */
550 WLAN_HDD_TM_ATTR_AFTER_LAST,
551 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
552};
553
554enum wlan_hdd_tm_cmd
555{
556 WLAN_HDD_TM_CMD_WLAN_HB = 1,
557};
558
559#define WLAN_HDD_TM_DATA_MAX_LEN 5000
560
561static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
562{
563 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
564 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
565 .len = WLAN_HDD_TM_DATA_MAX_LEN },
566};
567#endif /* WLAN_NL80211_TESTMODE */
568
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800569#ifdef FEATURE_WLAN_CH_AVOID
570/*
571 * FUNCTION: wlan_hdd_send_avoid_freq_event
572 * This is called when wlan driver needs to send vendor specific
573 * avoid frequency range event to userspace
574 */
575int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
576 tHddAvoidFreqList *pAvoidFreqList)
577{
578 struct sk_buff *vendor_event;
579
580 ENTER();
581
582 if (!pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
585 "%s: HDD context is null", __func__);
586 return -1;
587 }
588
589 if (!pAvoidFreqList)
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
592 "%s: pAvoidFreqList is null", __func__);
593 return -1;
594 }
595
596 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
597 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530598 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800599 GFP_KERNEL);
600 if (!vendor_event)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: cfg80211_vendor_event_alloc failed", __func__);
604 return -1;
605 }
606
607 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
608 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
609
610 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
611
612 EXIT();
613 return 0;
614}
615#endif /* FEATURE_WLAN_CH_AVOID */
616
Sunil Duttc69bccb2014-05-26 21:30:20 +0530617#ifdef WLAN_FEATURE_LINK_LAYER_STATS
618
619static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
620 struct sk_buff *vendor_event)
621{
622 if (nla_put_u8(vendor_event,
623 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
624 stats->rate.preamble) ||
625 nla_put_u8(vendor_event,
626 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
627 stats->rate.nss) ||
628 nla_put_u8(vendor_event,
629 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
630 stats->rate.bw) ||
631 nla_put_u8(vendor_event,
632 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
633 stats->rate.rateMcsIdx) ||
634 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
635 stats->rate.bitrate ) ||
636 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
637 stats->txMpdu ) ||
638 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
639 stats->rxMpdu ) ||
640 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
641 stats->mpduLost ) ||
642 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
643 stats->retries) ||
644 nla_put_u32(vendor_event,
645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
646 stats->retriesShort ) ||
647 nla_put_u32(vendor_event,
648 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
649 stats->retriesLong))
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("QCA_WLAN_VENDOR_ATTR put fail"));
653 return FALSE;
654 }
655 return TRUE;
656}
657
658static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
659 struct sk_buff *vendor_event)
660{
661 u32 i = 0;
662 struct nlattr *rateInfo;
663 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
664 stats->type) ||
665 nla_put(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
667 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
668 nla_put_u32(vendor_event,
669 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
670 stats->capabilities) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
673 stats->numRate))
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("QCA_WLAN_VENDOR_ATTR put fail"));
677 goto error;
678 }
679
680 rateInfo = nla_nest_start(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
682 for (i = 0; i < stats->numRate; i++)
683 {
684 struct nlattr *rates;
685 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
686 stats->rateStats +
687 (i * sizeof(tSirWifiRateStat)));
688 rates = nla_nest_start(vendor_event, i);
689
690 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
691 {
692 hddLog(VOS_TRACE_LEVEL_ERROR,
693 FL("QCA_WLAN_VENDOR_ATTR put fail"));
694 return FALSE;
695 }
696 nla_nest_end(vendor_event, rates);
697 }
698 nla_nest_end(vendor_event, rateInfo);
699
700 return TRUE;
701error:
702 return FALSE;
703}
704
705static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
706 struct sk_buff *vendor_event)
707{
708 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
709 stats->ac ) ||
710 nla_put_u32(vendor_event,
711 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
712 stats->txMpdu ) ||
713 nla_put_u32(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
715 stats->rxMpdu ) ||
716 nla_put_u32(vendor_event,
717 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
718 stats->txMcast ) ||
719 nla_put_u32(vendor_event,
720 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
721 stats->rxMcast ) ||
722 nla_put_u32(vendor_event,
723 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
724 stats->rxAmpdu ) ||
725 nla_put_u32(vendor_event,
726 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
727 stats->txAmpdu ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
730 stats->mpduLost )||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
733 stats->retries ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
736 stats->retriesShort ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
739 stats->retriesLong ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
742 stats->contentionTimeMin ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
745 stats->contentionTimeMax ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
748 stats->contentionTimeAvg ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
751 stats->contentionNumSamples ))
752 {
753 hddLog(VOS_TRACE_LEVEL_ERROR,
754 FL("QCA_WLAN_VENDOR_ATTR put fail") );
755 return FALSE;
756 }
757 return TRUE;
758}
759
760static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
761 struct sk_buff *vendor_event)
762{
763 if (nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
765 nla_put(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
767 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
770 stats->state ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
773 stats->roaming ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
776 stats->capabilities ) ||
777 nla_put(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
779 strlen(stats->ssid), stats->ssid) ||
780 nla_put(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
782 WNI_CFG_BSSID_LEN, stats->bssid) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
785 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
786 nla_put(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
788 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
789 )
790 {
791 hddLog(VOS_TRACE_LEVEL_ERROR,
792 FL("QCA_WLAN_VENDOR_ATTR put fail") );
793 return FALSE;
794 }
795 return TRUE;
796}
797
798static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
799 struct sk_buff *vendor_event)
800{
801 int i = 0;
802 struct nlattr *wmmInfo;
803 if (FALSE == put_wifi_interface_info(
804 &pWifiIfaceStat->info,
805 vendor_event))
806 {
807 hddLog(VOS_TRACE_LEVEL_ERROR,
808 FL("QCA_WLAN_VENDOR_ATTR put fail") );
809 return FALSE;
810
811 }
812
813 if (nla_put_u32(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
815 pWifiIfaceStat->beaconRx) ||
816 nla_put_u32(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
818 pWifiIfaceStat->mgmtRx) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
821 pWifiIfaceStat->mgmtActionRx) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
824 pWifiIfaceStat->mgmtActionTx) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
827 pWifiIfaceStat->rssiMgmt) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
830 pWifiIfaceStat->rssiData) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
833 pWifiIfaceStat->rssiAck))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail"));
837 return FALSE;
838 }
839
840 wmmInfo = nla_nest_start(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
842 for (i = 0; i < WIFI_AC_MAX; i++)
843 {
844 struct nlattr *wmmStats;
845 wmmStats = nla_nest_start(vendor_event, i);
846 if (FALSE == put_wifi_wmm_ac_stat(
847 &pWifiIfaceStat->AccessclassStats[i],
848 vendor_event))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
852 return FALSE;
853 }
854
855 nla_nest_end(vendor_event, wmmStats);
856 }
857 nla_nest_end(vendor_event, wmmInfo);
858 return TRUE;
859}
860
861static tSirWifiInterfaceMode
862 hdd_map_device_to_ll_iface_mode ( int deviceMode )
863{
864 switch (deviceMode)
865 {
866 case WLAN_HDD_INFRA_STATION:
867 return WIFI_INTERFACE_STA;
868 case WLAN_HDD_SOFTAP:
869 return WIFI_INTERFACE_SOFTAP;
870 case WLAN_HDD_P2P_CLIENT:
871 return WIFI_INTERFACE_P2P_CLIENT;
872 case WLAN_HDD_P2P_GO:
873 return WIFI_INTERFACE_P2P_GO;
874 case WLAN_HDD_IBSS:
875 return WIFI_INTERFACE_IBSS;
876 default:
877 /* Return Interface Mode as STA for all the unsupported modes */
878 return WIFI_INTERFACE_STA;
879 }
880}
881
882static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
883 tpSirWifiInterfaceInfo pInfo)
884{
885 v_U8_t *staMac = NULL;
886 hdd_station_ctx_t *pHddStaCtx;
887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
888 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
889
890 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
891
892 vos_mem_copy(pInfo->macAddr,
893 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
894
895 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
896 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
897 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
898 {
899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
900 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
901 {
902 pInfo->state = WIFI_DISCONNECTED;
903 }
904 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
905 {
906 hddLog(VOS_TRACE_LEVEL_ERROR,
907 "%s: Session ID %d, Connection is in progress", __func__,
908 pAdapter->sessionId);
909 pInfo->state = WIFI_ASSOCIATING;
910 }
911 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
912 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
913 {
914 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
915 hddLog(VOS_TRACE_LEVEL_ERROR,
916 "%s: client " MAC_ADDRESS_STR
917 " is in the middle of WPS/EAPOL exchange.", __func__,
918 MAC_ADDR_ARRAY(staMac));
919 pInfo->state = WIFI_AUTHENTICATING;
920 }
921 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
922 {
923 pInfo->state = WIFI_ASSOCIATED;
924 vos_mem_copy(pInfo->bssid,
925 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
926 vos_mem_copy(pInfo->ssid,
927 pHddStaCtx->conn_info.SSID.SSID.ssId,
928 pHddStaCtx->conn_info.SSID.SSID.length);
929 //NULL Terminate the string.
930 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
931 }
932 }
933 vos_mem_copy(pInfo->countryStr,
934 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
935
936 vos_mem_copy(pInfo->apCountryStr,
937 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
938
939 return TRUE;
940}
941
942/*
943 * hdd_link_layer_process_peer_stats () - This function is called after
944 * receiving Link Layer Peer statistics from FW.This function converts
945 * the firmware data to the NL data and sends the same to the kernel/upper
946 * layers.
947 */
948static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
949 v_VOID_t *pData)
950{
951 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
952 tpSirWifiRateStat pWifiRateStat;
953 tpSirWifiPeerStat pWifiPeerStat;
954 tpSirWifiPeerInfo pWifiPeerInfo;
955 struct nlattr *peerInfo;
956 struct sk_buff *vendor_event;
957 int status, i;
958
959 status = wlan_hdd_validate_context(pHddCtx);
960 if (0 != status)
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("HDD context is not valid") );
964 return;
965 }
966
967 pWifiPeerStat = (tpSirWifiPeerStat) pData;
968
969 hddLog(VOS_TRACE_LEVEL_INFO,
970 "LL_STATS_PEER_ALL : numPeers %u",
971 pWifiPeerStat->numPeers);
972 {
973 for (i = 0; i < pWifiPeerStat->numPeers; i++)
974 {
975 pWifiPeerInfo = (tpSirWifiPeerInfo)
976 ((uint8 *)pWifiPeerStat->peerInfo +
977 ( i * sizeof(tSirWifiPeerInfo)));
978
979 hddLog(VOS_TRACE_LEVEL_INFO,
980 " %d) LL_STATS Channel Stats "
981 " Peer Type %u "
982 " peerMacAddress %pM "
983 " capabilities 0x%x "
984 " numRate %u ",
985 i,
986 pWifiPeerInfo->type,
987 pWifiPeerInfo->peerMacAddress,
988 pWifiPeerInfo->capabilities,
989 pWifiPeerInfo->numRate);
990 {
991 int j;
992 for (j = 0; j < pWifiPeerInfo->numRate; j++)
993 {
994 pWifiRateStat = (tpSirWifiRateStat)
995 ((tANI_U8 *) pWifiPeerInfo->rateStats +
996 ( j * sizeof(tSirWifiRateStat)));
997
998 hddLog(VOS_TRACE_LEVEL_INFO,
999 " peer Rate Stats "
1000 " preamble %u "
1001 " nss %u "
1002 " bw %u "
1003 " rateMcsIdx %u "
1004 " reserved %u "
1005 " bitrate %u "
1006 " txMpdu %u "
1007 " rxMpdu %u "
1008 " mpduLost %u "
1009 " retries %u "
1010 " retriesShort %u "
1011 " retriesLong %u",
1012 pWifiRateStat->rate.preamble,
1013 pWifiRateStat->rate.nss,
1014 pWifiRateStat->rate.bw,
1015 pWifiRateStat->rate.rateMcsIdx,
1016 pWifiRateStat->rate.reserved,
1017 pWifiRateStat->rate.bitrate,
1018 pWifiRateStat->txMpdu,
1019 pWifiRateStat->rxMpdu,
1020 pWifiRateStat->mpduLost,
1021 pWifiRateStat->retries,
1022 pWifiRateStat->retriesShort,
1023 pWifiRateStat->retriesLong);
1024 }
1025 }
1026 }
1027 }
1028
1029 /*
1030 * Allocate a size of 4096 for the peer stats comprising
1031 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1032 * sizeof (tSirWifiRateStat).Each field is put with an
1033 * NL attribute.The size of 4096 is considered assuming
1034 * that number of rates shall not exceed beyond 50 with
1035 * the sizeof (tSirWifiRateStat) being 32.
1036 */
1037 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1038 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1039 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1040 GFP_KERNEL);
1041 if (!vendor_event)
1042 {
1043 hddLog(VOS_TRACE_LEVEL_ERROR,
1044 "%s: cfg80211_vendor_event_alloc failed",
1045 __func__);
1046 return;
1047 }
1048 if (nla_put_u32(vendor_event,
1049 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1050 pWifiPeerStat->numPeers))
1051 {
1052 hddLog(VOS_TRACE_LEVEL_ERROR,
1053 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1054 kfree_skb(vendor_event);
1055 return;
1056 }
1057
1058 peerInfo = nla_nest_start(vendor_event,
1059 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1060
1061 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1062 pWifiPeerStat->peerInfo);
1063
1064 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1065 {
1066 struct nlattr *peers = nla_nest_start(vendor_event, i);
1067 int numRate = pWifiPeerInfo->numRate;
1068
1069 if (FALSE == put_wifi_peer_info(
1070 pWifiPeerInfo, vendor_event))
1071 {
1072 hddLog(VOS_TRACE_LEVEL_ERROR,
1073 "%s: put_wifi_peer_info put fail", __func__);
1074 kfree_skb(vendor_event);
1075 return;
1076 }
1077
1078 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1079 pWifiPeerStat->peerInfo +
1080 (i * sizeof(tSirWifiPeerInfo)) +
1081 (numRate * sizeof (tSirWifiRateStat)));
1082 nla_nest_end(vendor_event, peers);
1083 }
1084 nla_nest_end(vendor_event, peerInfo);
1085 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1086}
1087
1088/*
1089 * hdd_link_layer_process_iface_stats () - This function is called after
1090 * receiving Link Layer Interface statistics from FW.This function converts
1091 * the firmware data to the NL data and sends the same to the kernel/upper
1092 * layers.
1093 */
1094static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1095 v_VOID_t *pData)
1096{
1097 tpSirWifiIfaceStat pWifiIfaceStat;
1098 struct sk_buff *vendor_event;
1099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1100 int status;
1101
1102 status = wlan_hdd_validate_context(pHddCtx);
1103 if (0 != status)
1104 {
1105 hddLog(VOS_TRACE_LEVEL_ERROR,
1106 FL("HDD context is not valid") );
1107 return;
1108 }
1109 /*
1110 * Allocate a size of 4096 for the interface stats comprising
1111 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1112 * assuming that all these fit with in the limit.Please take
1113 * a call on the limit based on the data requirements on
1114 * interface statistics.
1115 */
1116 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1117 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1118 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1119 GFP_KERNEL);
1120 if (!vendor_event)
1121 {
1122 hddLog(VOS_TRACE_LEVEL_ERROR,
1123 FL("cfg80211_vendor_event_alloc failed") );
1124 return;
1125 }
1126
1127 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1128
1129 hddLog(VOS_TRACE_LEVEL_INFO,
1130 "WMI_LINK_STATS_IFACE Data");
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 "LL_STATS_IFACE: "
1134 " Mode %u "
1135 " MAC %pM "
1136 " State %u "
1137 " Roaming %u "
1138 " capabilities 0x%x "
1139 " SSID %s "
1140 " BSSID %pM",
1141 pWifiIfaceStat->info.mode,
1142 pWifiIfaceStat->info.macAddr,
1143 pWifiIfaceStat->info.state,
1144 pWifiIfaceStat->info.roaming,
1145 pWifiIfaceStat->info.capabilities,
1146 pWifiIfaceStat->info.ssid,
1147 pWifiIfaceStat->info.bssid);
1148
1149 hddLog(VOS_TRACE_LEVEL_INFO,
1150 " AP country str: %c%c%c",
1151 pWifiIfaceStat->info.apCountryStr[0],
1152 pWifiIfaceStat->info.apCountryStr[1],
1153 pWifiIfaceStat->info.apCountryStr[2]);
1154
1155
1156 hddLog(VOS_TRACE_LEVEL_INFO,
1157 " Country Str Association: %c%c%c",
1158 pWifiIfaceStat->info.countryStr[0],
1159 pWifiIfaceStat->info.countryStr[1],
1160 pWifiIfaceStat->info.countryStr[2]);
1161
1162 hddLog(VOS_TRACE_LEVEL_INFO,
1163 " beaconRx %u "
1164 " mgmtRx %u "
1165 " mgmtActionRx %u "
1166 " mgmtActionTx %u "
1167 " rssiMgmt %u "
1168 " rssiData %u "
1169 " rssiAck %u",
1170 pWifiIfaceStat->beaconRx,
1171 pWifiIfaceStat->mgmtRx,
1172 pWifiIfaceStat->mgmtActionRx,
1173 pWifiIfaceStat->mgmtActionTx,
1174 pWifiIfaceStat->rssiMgmt,
1175 pWifiIfaceStat->rssiData,
1176 pWifiIfaceStat->rssiAck );
1177
1178
1179 {
1180 int i;
1181 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_INFO,
1184
1185 " %d) LL_STATS IFACE: "
1186 " ac: %u txMpdu: %u "
1187 " rxMpdu: %u txMcast: %u "
1188 " rxMcast: %u rxAmpdu: %u "
1189 " txAmpdu: %u mpduLost: %u "
1190 " retries: %u retriesShort: %u "
1191 " retriesLong: %u contentionTimeMin: %u "
1192 " contentionTimeMax: %u contentionTimeAvg: %u "
1193 " contentionNumSamples: %u",
1194 i,
1195 pWifiIfaceStat->AccessclassStats[i].ac,
1196 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1197 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1198 pWifiIfaceStat->AccessclassStats[i].txMcast,
1199 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1200 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1201 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1202 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1203 pWifiIfaceStat->AccessclassStats[i].retries,
1204 pWifiIfaceStat->
1205 AccessclassStats[i].retriesShort,
1206 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1207 pWifiIfaceStat->
1208 AccessclassStats[i].contentionTimeMin,
1209 pWifiIfaceStat->
1210 AccessclassStats[i].contentionTimeMax,
1211 pWifiIfaceStat->
1212 AccessclassStats[i].contentionTimeAvg,
1213 pWifiIfaceStat->
1214 AccessclassStats[i].contentionNumSamples);
1215
1216 }
1217 }
1218
1219 if (FALSE == hdd_get_interface_info( pAdapter,
1220 &pWifiIfaceStat->info))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 FL("hdd_get_interface_info get fail") );
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1229 vendor_event))
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("put_wifi_iface_stats fail") );
1233 kfree_skb(vendor_event);
1234 return;
1235 }
1236 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1237}
1238
1239/*
1240 * hdd_link_layer_process_radio_stats () - This function is called after
1241 * receiving Link Layer Radio statistics from FW.This function converts
1242 * the firmware data to the NL data and sends the same to the kernel/upper
1243 * layers.
1244 */
1245static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1246 v_VOID_t *pData)
1247{
1248 int status, i;
1249 tpSirWifiRadioStat pWifiRadioStat;
1250 tpSirWifiChannelStats pWifiChannelStats;
1251 struct sk_buff *vendor_event;
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1253 struct nlattr *chList;
1254
1255 status = wlan_hdd_validate_context(pHddCtx);
1256 if (0 != status)
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("HDD context is not valid") );
1260 return;
1261 }
1262 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1263
1264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 "LL_STATS_RADIO"
1266 " radio is %d onTime is %u "
1267 " txTime is %u rxTime is %u "
1268 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301269 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 " onTimePnoScan is %u onTimeHs20 is %u "
1271 " numChannels is %u",
1272 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1273 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1274 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301275 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301276 pWifiRadioStat->onTimeRoamScan,
1277 pWifiRadioStat->onTimePnoScan,
1278 pWifiRadioStat->onTimeHs20,
1279 pWifiRadioStat->numChannels);
1280 /*
1281 * Allocate a size of 4096 for the Radio stats comprising
1282 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1283 * (tSirWifiChannelStats).Each channel data is put with an
1284 * NL attribute.The size of 4096 is considered assuming that
1285 * number of channels shall not exceed beyond 60 with the
1286 * sizeof (tSirWifiChannelStats) being 24 bytes.
1287 */
1288
1289 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1290 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1291 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1292 GFP_KERNEL);
1293
1294 if (!vendor_event)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 FL("cfg80211_vendor_event_alloc failed") );
1298 return;
1299 }
1300
1301 if (nla_put_u32(vendor_event,
1302 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1303 pWifiRadioStat->radio) ||
1304 nla_put_u32(vendor_event,
1305 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1306 pWifiRadioStat->onTime) ||
1307 nla_put_u32(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1309 pWifiRadioStat->txTime) ||
1310 nla_put_u32(vendor_event,
1311 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1312 pWifiRadioStat->rxTime) ||
1313 nla_put_u32(vendor_event,
1314 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1315 pWifiRadioStat->onTimeScan) ||
1316 nla_put_u32(vendor_event,
1317 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1318 pWifiRadioStat->onTimeNbd) ||
1319 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1321 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1324 pWifiRadioStat->onTimeRoamScan) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1327 pWifiRadioStat->onTimePnoScan) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1330 pWifiRadioStat->onTimeHs20) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1333 pWifiRadioStat->numChannels))
1334 {
1335 hddLog(VOS_TRACE_LEVEL_ERROR,
1336 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1337 kfree_skb(vendor_event);
1338 return ;
1339 }
1340
1341 chList = nla_nest_start(vendor_event,
1342 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1343 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1344 {
1345 struct nlattr *chInfo;
1346
1347 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1348 pWifiRadioStat->channels +
1349 (i * sizeof(tSirWifiChannelStats)));
1350
1351 hddLog(VOS_TRACE_LEVEL_INFO,
1352 " %d) Channel Info"
1353 " width is %u "
1354 " CenterFreq %u "
1355 " CenterFreq0 %u "
1356 " CenterFreq1 %u "
1357 " onTime %u "
1358 " ccaBusyTime %u",
1359 i,
1360 pWifiChannelStats->channel.width,
1361 pWifiChannelStats->channel.centerFreq,
1362 pWifiChannelStats->channel.centerFreq0,
1363 pWifiChannelStats->channel.centerFreq1,
1364 pWifiChannelStats->onTime,
1365 pWifiChannelStats->ccaBusyTime);
1366
1367
1368 chInfo = nla_nest_start(vendor_event, i);
1369
1370 if (nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1372 pWifiChannelStats->channel.width) ||
1373 nla_put_u32(vendor_event,
1374 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1375 pWifiChannelStats->channel.centerFreq) ||
1376 nla_put_u32(vendor_event,
1377 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1378 pWifiChannelStats->channel.centerFreq0) ||
1379 nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1381 pWifiChannelStats->channel.centerFreq1) ||
1382 nla_put_u32(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1384 pWifiChannelStats->onTime) ||
1385 nla_put_u32(vendor_event,
1386 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1387 pWifiChannelStats->ccaBusyTime))
1388 {
1389 hddLog(VOS_TRACE_LEVEL_ERROR,
1390 FL("cfg80211_vendor_event_alloc failed") );
1391 kfree_skb(vendor_event);
1392 return ;
1393 }
1394 nla_nest_end(vendor_event, chInfo);
1395 }
1396 nla_nest_end(vendor_event, chList);
1397
1398 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1399 return;
1400}
1401
1402/*
1403 * hdd_link_layer_stats_ind_callback () - This function is called after
1404 * receiving Link Layer indications from FW.This callback converts the firmware
1405 * data to the NL data and send the same to the kernel/upper layers.
1406 */
1407static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1408 int indType,
1409 void *pRsp )
1410{
1411 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCtx;
1412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1413 int status;
1414
1415 status = wlan_hdd_validate_context(pHddCtx);
1416
1417 if (0 != status)
1418 {
1419 hddLog(VOS_TRACE_LEVEL_ERROR,
1420 FL("HDD context is not valid"));
1421 return;
1422 }
1423
1424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1425 "%s: Link Layer Indication indType: %d", __func__, indType);
1426 switch (indType)
1427 {
1428 case SIR_HAL_LL_STATS_RESULTS_RSP:
1429 {
1430 tpSirLLStatsResults linkLayerStatsResults =
1431 (tpSirLLStatsResults)pRsp;
1432
1433
1434 hddLog(VOS_TRACE_LEVEL_INFO,
1435 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1436 hddLog(VOS_TRACE_LEVEL_INFO,
1437 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1438 linkLayerStatsResults->paramId);
1439 hddLog(VOS_TRACE_LEVEL_INFO,
1440 "LL_STATS RESULTS RESPONSE ifaceId = %u",
1441 linkLayerStatsResults->ifaceId);
1442 hddLog(VOS_TRACE_LEVEL_INFO,
1443 "LL_STATS RESULTS RESPONSE respId = %u",
1444 linkLayerStatsResults->respId);
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1447 linkLayerStatsResults->moreResultToFollow);
1448 hddLog(VOS_TRACE_LEVEL_INFO,
1449 "LL_STATS RESULTS RESPONSE result = %p",
1450 linkLayerStatsResults->result);
1451 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1452 {
1453 hdd_link_layer_process_radio_stats(pAdapter,
1454 (v_VOID_t *)linkLayerStatsResults->result);
1455 }
1456 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1457 {
1458 hdd_link_layer_process_iface_stats(pAdapter,
1459 (v_VOID_t *)linkLayerStatsResults->result);
1460 }
1461 else if ( linkLayerStatsResults->paramId &
1462 WMI_LINK_STATS_ALL_PEER )
1463 {
1464 hdd_link_layer_process_peer_stats(pAdapter,
1465 (v_VOID_t *)linkLayerStatsResults->result);
1466 } /* WMI_LINK_STATS_ALL_PEER */
1467 else
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
1470 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1471 }
1472
1473 break;
1474 }
1475 default:
1476 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1477 break;
1478 }
1479 return;
1480}
1481
1482const struct
1483nla_policy
1484qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1485{
1486 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1487 { .type = NLA_U32 },
1488 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1489 { .type = NLA_U32 },
1490};
1491
1492static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1493 struct wireless_dev *wdev,
1494 void *data,
1495 int data_len)
1496{
1497 int status;
1498 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301499 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301500 struct net_device *dev = wdev->netdev;
1501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1503
1504 status = wlan_hdd_validate_context(pHddCtx);
1505 if (0 != status)
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 FL("HDD context is not valid"));
1509 return -EINVAL;
1510 }
1511
1512 if (NULL == pAdapter)
1513 {
1514 hddLog(VOS_TRACE_LEVEL_ERROR,
1515 FL("HDD adapter is Null"));
1516 return -ENODEV;
1517 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301518 /* check the LLStats Capability */
1519 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1520 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1521 {
1522 hddLog(VOS_TRACE_LEVEL_ERROR,
1523 FL("Link Layer Statistics not supported by Firmware"));
1524 return -EINVAL;
1525 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301526
1527 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1528 (struct nlattr *)data,
1529 data_len, qca_wlan_vendor_ll_set_policy))
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1532 return -EINVAL;
1533 }
1534 if (!tb_vendor
1535 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1538 return -EINVAL;
1539 }
1540 if (!tb_vendor[
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1542 {
1543 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1544 return -EINVAL;
1545 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301546 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301547 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301548
Dino Mycledf0a5d92014-07-04 09:41:55 +05301549 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550 nla_get_u32(
1551 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1552
Dino Mycledf0a5d92014-07-04 09:41:55 +05301553 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 nla_get_u32(
1555 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1556
1557 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1558 * Hence the interface staId start from 1. Hence the staId matching the
1559 * interface in the firmware is sessionId + 1.
1560 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301561 linkLayerStatsSetReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562
1563
1564 hddLog(VOS_TRACE_LEVEL_INFO,
1565 "LL_STATS_SET reqId = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301566 linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301568 "LL_STATS_SET staId = %d", linkLayerStatsSetReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301571 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 hddLog(VOS_TRACE_LEVEL_INFO,
1573 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301574 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
1576 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1577 pHddCtx->hHal,
1578 pAdapter->sessionId,
1579 hdd_link_layer_stats_ind_callback,
1580 pAdapter))
1581 {
1582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1583 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584 return -EINVAL;
1585
1586 }
1587 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301588 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1591 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 return -EINVAL;
1593 }
1594
1595 pAdapter->isLinkLayerStatsSet = 1;
1596
1597 return 0;
1598}
1599
1600const struct
1601nla_policy
1602qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1603{
1604 /* Unsigned 32bit value provided by the caller issuing the GET stats
1605 * command. When reporting
1606 * the stats results, the driver uses the same value to indicate
1607 * which GET request the results
1608 * correspond to.
1609 */
1610 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1611
1612 /* Unsigned 32bit value . bit mask to identify what statistics are
1613 requested for retrieval */
1614 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1615};
1616
1617static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1618 struct wireless_dev *wdev,
1619 void *data,
1620 int data_len)
1621{
1622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1623 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301624 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 struct net_device *dev = wdev->netdev;
1626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1627 int status;
1628
1629 status = wlan_hdd_validate_context(pHddCtx);
1630 if (0 != status)
1631 {
1632 hddLog(VOS_TRACE_LEVEL_ERROR,
1633 FL("HDD context is not valid"));
1634 return -EINVAL ;
1635 }
1636
1637 if (NULL == pAdapter)
1638 {
1639 hddLog(VOS_TRACE_LEVEL_FATAL,
1640 "%s: HDD adapter is Null", __func__);
1641 return -ENODEV;
1642 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301643 /* check the LLStats Capability */
1644 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1645 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1646 {
1647 hddLog(VOS_TRACE_LEVEL_ERROR,
1648 FL("Link Layer Statistics not supported by Firmware"));
1649 return -EINVAL;
1650 }
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652
1653 if (!pAdapter->isLinkLayerStatsSet)
1654 {
1655 hddLog(VOS_TRACE_LEVEL_FATAL,
1656 "%s: isLinkLayerStatsSet : %d",
1657 __func__, pAdapter->isLinkLayerStatsSet);
1658 return -EINVAL;
1659 }
1660
1661 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1662 (struct nlattr *)data,
1663 data_len, qca_wlan_vendor_ll_get_policy))
1664 {
1665 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1666 return -EINVAL;
1667 }
1668
1669 if (!tb_vendor
1670 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1671 {
1672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1673 return -EINVAL;
1674 }
1675
1676 if (!tb_vendor
1677 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1680 return -EINVAL;
1681 }
1682
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683
Dino Mycledf0a5d92014-07-04 09:41:55 +05301684 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 nla_get_u32( tb_vendor[
1686 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 nla_get_u32( tb_vendor[
1689 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1690
1691 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1692 * Hence the interface staId start from 1. Hence the staId matching the
1693 * interface in the firmware is sessionId + 1.
1694 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301695 linkLayerStatsGetReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696
1697 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301698 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301699 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301700 "LL_STATS_GET staId = %d", linkLayerStatsGetReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701 hddLog(VOS_TRACE_LEVEL_INFO,
1702 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704
1705 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301707 {
1708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1709 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710 return -EINVAL;
1711 }
1712 return 0;
1713}
1714
1715const struct
1716nla_policy
1717qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1718{
1719 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1721 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1723};
1724
1725static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1726 struct wireless_dev *wdev,
1727 void *data,
1728 int data_len)
1729{
1730 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1731 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733 struct net_device *dev = wdev->netdev;
1734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1735 u32 statsClearReqMask;
1736 u8 stopReq;
1737 int status;
1738
1739 status = wlan_hdd_validate_context(pHddCtx);
1740 if (0 != status)
1741 {
1742 hddLog(VOS_TRACE_LEVEL_ERROR,
1743 FL("HDD context is not valid"));
1744 return -EINVAL;
1745 }
1746
1747 if (NULL == pAdapter)
1748 {
1749 hddLog(VOS_TRACE_LEVEL_FATAL,
1750 "%s: HDD adapter is Null", __func__);
1751 return -ENODEV;
1752 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301753 /* check the LLStats Capability */
1754 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1755 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR,
1758 FL("Enable LLStats Capability"));
1759 return -EINVAL;
1760 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761
1762 if (!pAdapter->isLinkLayerStatsSet)
1763 {
1764 hddLog(VOS_TRACE_LEVEL_FATAL,
1765 "%s: isLinkLayerStatsSet : %d",
1766 __func__, pAdapter->isLinkLayerStatsSet);
1767 return -EINVAL;
1768 }
1769
1770 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1771 (struct nlattr *)data,
1772 data_len, qca_wlan_vendor_ll_clr_policy))
1773 {
1774 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1775 return -EINVAL;
1776 }
1777
1778 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1779
1780 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1781 {
1782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1783 return -EINVAL;
1784
1785 }
1786
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787
Dino Mycledf0a5d92014-07-04 09:41:55 +05301788 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 nla_get_u32(
1790 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1791
Dino Mycledf0a5d92014-07-04 09:41:55 +05301792 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301793 nla_get_u8(
1794 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1795
1796 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798
1799 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1800 * Hence the interface staId start from 1. Hence the staId matching the
1801 * interface in the firmware is sessionId + 1.
1802 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301803 linkLayerStatsClearReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301804
1805 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301806 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301808 "LL_STATS_CLEAR staId = %d", linkLayerStatsClearReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301814 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815
1816 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 {
1819 struct sk_buff *temp_skbuff;
1820 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1821 2 * sizeof(u32) +
1822 NLMSG_HDRLEN);
1823
1824 if (temp_skbuff != NULL)
1825 {
1826
1827 if (nla_put_u32(temp_skbuff,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1829 statsClearReqMask) ||
1830 nla_put_u32(temp_skbuff,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1832 stopReq))
1833 {
1834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1835 kfree_skb(temp_skbuff);
1836 return -EINVAL;
1837 }
1838 /* If the ask is to stop the stats collection as part of clear
1839 * (stopReq = 1) , ensure that no further requests of get
1840 * go to the firmware by having isLinkLayerStatsSet set to 0.
1841 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301842 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 * case the firmware is just asked to clear the statistics.
1844 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301845 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846 pAdapter->isLinkLayerStatsSet = 0;
1847 return cfg80211_vendor_cmd_reply(temp_skbuff);
1848 }
1849 return -ENOMEM;
1850 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301851 return -EINVAL;
1852}
1853#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1854
Dino Mycle6fb96c12014-06-10 11:52:40 +05301855#ifdef WLAN_FEATURE_EXTSCAN
1856static const struct nla_policy
1857wlan_hdd_extscan_config_policy
1858 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1859{
1860 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1861 { .type = NLA_U32 },
1862 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1863 { .type = NLA_U32 },
1864 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1866 { .type = NLA_U32 },
1867 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1868 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1869
1870 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1873 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1874 { .type = NLA_U8 },
1875 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1876 { .type = NLA_U32 },
1877 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1878 { .type = NLA_U32 },
1879 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1880 { .type = NLA_U32 },
1881 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1882 { .type = NLA_U8 },
1883 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1884 { .type = NLA_U8 },
1885 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1886 { .type = NLA_U8 },
1887
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1889 { .type = NLA_U32 },
1890 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1891 { .type = NLA_UNSPEC },
1892 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1893 { .type = NLA_S32 },
1894 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1895 { .type = NLA_S32 },
1896 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1897 { .type = NLA_U32 },
1898 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1899 { .type = NLA_U32 },
1900 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1901 { .type = NLA_U32 },
1902 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1903 = { .type = NLA_U32 },
1904 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1905 { .type = NLA_U32 },
1906 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1907 NLA_U32 },
1908};
1909
1910static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1911{
1912 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1913 struct sk_buff *skb = NULL;
1914 tpSirEXTScanCapabilitiesEvent pData =
1915 (tpSirEXTScanCapabilitiesEvent) pMsg;
1916
1917 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1919 "or pData(%p) is null"), pData);
1920 return;
1921 }
1922
1923 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1924 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1925 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1926 GFP_KERNEL);
1927
1928 if (!skb) {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("cfg80211_vendor_event_alloc failed"));
1931 return;
1932 }
1933
1934 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1935 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1936 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1937 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1938 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1939 pData->maxRssiSampleSize);
1940 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1941 pData->maxScanReportingThreshold);
1942 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1944 pData->maxSignificantWifiChangeAPs);
1945 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1946 pData->maxBsidHistoryEntries);
1947
1948 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1949 pData->requestId) ||
1950 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1951 nla_put_u32(skb,
1952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1953 pData->scanCacheSize) ||
1954 nla_put_u32(skb,
1955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1956 pData->scanBuckets) ||
1957 nla_put_u32(skb,
1958 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1959 pData->maxApPerScan) ||
1960 nla_put_u32(skb,
1961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1962 pData->maxRssiSampleSize) ||
1963 nla_put_u32(skb,
1964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1965 pData->maxScanReportingThreshold) ||
1966 nla_put_u32(skb,
1967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1968 pData->maxHotlistAPs) ||
1969 nla_put_u32(skb,
1970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1971 pData->maxSignificantWifiChangeAPs) ||
1972 nla_put_u32(skb,
1973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1974 pData->maxBsidHistoryEntries)) {
1975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1976 goto nla_put_failure;
1977 }
1978
1979 cfg80211_vendor_event(skb, GFP_KERNEL);
1980 return;
1981
1982nla_put_failure:
1983 kfree_skb(skb);
1984 return;
1985}
1986
1987
1988static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1989{
1990 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1991 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1992 struct sk_buff *skb = NULL;
1993 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
1994
1995
1996 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1998 "or pData(%p) is null"), pData);
1999 return;
2000 }
2001
2002 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2003 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2004 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2005 GFP_KERNEL);
2006
2007 if (!skb) {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
2009 FL("cfg80211_vendor_event_alloc failed"));
2010 return;
2011 }
2012 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2013 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2014 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2015
2016 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2017 pData->requestId) ||
2018 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2020 goto nla_put_failure;
2021 }
2022
2023 /*
2024 * Store the Request ID for comparing with the requestID obtained
2025 * in other requests.HDD shall return a failure is the extscan_stop
2026 * request is issued with a different requestId as that of the
2027 * extscan_start request. Also, This requestId shall be used while
2028 * indicating the full scan results to the upper layers.
2029 * The requestId is stored with the assumption that the firmware
2030 * shall return the ext scan start request's requestId in ext scan
2031 * start response.
2032 */
2033 if (pData->status == 0)
2034 pMac->sme.extScanStartReqId = pData->requestId;
2035
2036
2037 cfg80211_vendor_event(skb, GFP_KERNEL);
2038 return;
2039
2040nla_put_failure:
2041 kfree_skb(skb);
2042 return;
2043}
2044
2045
2046static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2047{
2048 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2049 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2050 struct sk_buff *skb = NULL;
2051
2052 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2054 "or pData(%p) is null"), pData);
2055 return;
2056 }
2057
2058 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2059 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2060 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2061 GFP_KERNEL);
2062
2063 if (!skb) {
2064 hddLog(VOS_TRACE_LEVEL_ERROR,
2065 FL("cfg80211_vendor_event_alloc failed"));
2066 return;
2067 }
2068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2069 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2070
2071 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2072 pData->requestId) ||
2073 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2075 goto nla_put_failure;
2076 }
2077
2078 cfg80211_vendor_event(skb, GFP_KERNEL);
2079 return;
2080
2081nla_put_failure:
2082 kfree_skb(skb);
2083 return;
2084}
2085
2086
2087static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2088 void *pMsg)
2089{
2090 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2091 struct sk_buff *skb = NULL;
2092 tpSirEXTScanSetBssidHotListRspParams pData =
2093 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2094
2095 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2097 "or pData(%p) is null"), pData);
2098 return;
2099 }
2100 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2101 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2102 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2103 GFP_KERNEL);
2104
2105 if (!skb) {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed"));
2108 return;
2109 }
2110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2111 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2112 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2113
2114 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2115 pData->requestId) ||
2116 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2118 goto nla_put_failure;
2119 }
2120
2121 cfg80211_vendor_event(skb, GFP_KERNEL);
2122 return;
2123
2124nla_put_failure:
2125 kfree_skb(skb);
2126 return;
2127}
2128
2129static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2130 void *pMsg)
2131{
2132 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2133 struct sk_buff *skb = NULL;
2134 tpSirEXTScanResetBssidHotlistRspParams pData =
2135 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2136
2137 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2139 "or pData(%p) is null"), pData);
2140 return;
2141 }
2142
2143 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2144 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2145 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2146 GFP_KERNEL);
2147
2148 if (!skb) {
2149 hddLog(VOS_TRACE_LEVEL_ERROR,
2150 FL("cfg80211_vendor_event_alloc failed"));
2151 return;
2152 }
2153 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2154 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2155
2156 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2157 pData->requestId) ||
2158 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2160 goto nla_put_failure;
2161 }
2162
2163 cfg80211_vendor_event(skb, GFP_KERNEL);
2164 return;
2165
2166nla_put_failure:
2167 kfree_skb(skb);
2168 return;
2169}
2170
2171
2172static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2173 void *pMsg)
2174{
2175 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2176 struct sk_buff *skb = NULL;
2177 tpSirEXTScanSetSignificantChangeRspParams pData =
2178 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2179
2180 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2182 "or pData(%p) is null"), pData);
2183 return;
2184 }
2185
2186 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2187 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2188 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2189 GFP_KERNEL);
2190
2191 if (!skb) {
2192 hddLog(VOS_TRACE_LEVEL_ERROR,
2193 FL("cfg80211_vendor_event_alloc failed"));
2194 return;
2195 }
2196 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2197 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2198 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2199
2200 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2201 pData->requestId) ||
2202 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2204 goto nla_put_failure;
2205 }
2206
2207 cfg80211_vendor_event(skb, GFP_KERNEL);
2208 return;
2209
2210nla_put_failure:
2211 kfree_skb(skb);
2212 return;
2213}
2214
2215
2216static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2217 void *pMsg)
2218{
2219 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2220 struct sk_buff *skb = NULL;
2221 tpSirEXTScanResetSignificantChangeRspParams pData =
2222 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2223
2224 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2226 "or pData(%p) is null"), pData);
2227 return;
2228 }
2229
2230 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2231 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2232 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2233 GFP_KERNEL);
2234
2235 if (!skb) {
2236 hddLog(VOS_TRACE_LEVEL_ERROR,
2237 FL("cfg80211_vendor_event_alloc failed"));
2238 return;
2239 }
2240 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2241 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2242 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2243
2244 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2245 pData->requestId) ||
2246 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2248 goto nla_put_failure;
2249 }
2250
2251 cfg80211_vendor_event(skb, GFP_KERNEL);
2252 return;
2253
2254nla_put_failure:
2255 kfree_skb(skb);
2256 return;
2257}
2258
2259static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2260 void *pMsg)
2261{
2262 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2263 struct sk_buff *skb = NULL;
2264 tANI_U32 i = 0, j, resultsPerEvent;
2265 tANI_S32 totalResults;
2266 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2267 tpSirWifiScanResult pSirWifiScanResult;
2268
2269 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2271 "or pData(%p) is null"), pData);
2272 return;
2273 }
2274 totalResults = pData->numOfAps;
2275 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2276 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2277 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2278
2279 do{
2280 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2281 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2282 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2283
2284 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2285 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2286 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2287 GFP_KERNEL);
2288
2289 if (!skb) {
2290 hddLog(VOS_TRACE_LEVEL_ERROR,
2291 FL("cfg80211_vendor_event_alloc failed"));
2292 return;
2293 }
2294
2295 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2296
2297 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2298 pData->requestId) ||
2299 nla_put_u32(skb,
2300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2301 resultsPerEvent)) {
2302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2303 goto fail;
2304 }
2305 if (nla_put_u8(skb,
2306 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2307 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2308 {
2309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2310 goto fail;
2311 }
2312
2313 if (resultsPerEvent) {
2314 struct nlattr *aps;
2315
2316 aps = nla_nest_start(skb,
2317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2318 if (!aps)
2319 {
2320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2321 goto fail;
2322 }
2323
2324 for (j = 0; j < resultsPerEvent; j++, i++) {
2325 struct nlattr *ap;
2326 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2327 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2328
2329 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2330 "Ssid (%s)"
2331 "Bssid: %pM "
2332 "Channel (%u)"
2333 "Rssi (%d)"
2334 "RTT (%u)"
2335 "RTT_SD (%u)",
2336 i,
2337 pSirWifiScanResult->ts,
2338 pSirWifiScanResult->ssid,
2339 pSirWifiScanResult->bssid,
2340 pSirWifiScanResult->channel,
2341 pSirWifiScanResult->rssi,
2342 pSirWifiScanResult->rtt,
2343 pSirWifiScanResult->rtt_sd);
2344
2345 ap = nla_nest_start(skb, j + 1);
2346 if (!ap)
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2349 goto fail;
2350 }
2351
2352 if (nla_put_u64(skb,
2353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2354 pSirWifiScanResult->ts) )
2355 {
2356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2357 goto fail;
2358 }
2359 if (nla_put(skb,
2360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2361 sizeof(pSirWifiScanResult->ssid),
2362 pSirWifiScanResult->ssid) )
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2365 goto fail;
2366 }
2367 if (nla_put(skb,
2368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2369 sizeof(pSirWifiScanResult->bssid),
2370 pSirWifiScanResult->bssid) )
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2373 goto fail;
2374 }
2375 if (nla_put_u32(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2377 pSirWifiScanResult->channel) )
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2380 goto fail;
2381 }
2382 if (nla_put_u32(skb,
2383 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2384 pSirWifiScanResult->rssi) )
2385 {
2386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2387 goto fail;
2388 }
2389 if (nla_put_u32(skb,
2390 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2391 pSirWifiScanResult->rtt) )
2392 {
2393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2394 goto fail;
2395 }
2396 if (nla_put_u32(skb,
2397 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2398 pSirWifiScanResult->rtt_sd))
2399 {
2400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2401 goto fail;
2402 }
2403
2404 nla_nest_end(skb, ap);
2405 }
2406 nla_nest_end(skb, aps);
2407
2408 }
2409 cfg80211_vendor_event(skb, GFP_KERNEL);
2410 } while (totalResults > 0);
2411
2412 return;
2413fail:
2414 kfree_skb(skb);
2415 return;
2416}
2417
2418static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2419 void *pMsg)
2420{
2421 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2422 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2423 struct sk_buff *skb = NULL;
2424 tANI_U32 i;
2425
2426 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2428 "or pData(%p) is null"), pData);
2429 return;
2430 }
2431
2432 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2433 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2434 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2435 GFP_KERNEL);
2436
2437 if (!skb) {
2438 hddLog(VOS_TRACE_LEVEL_ERROR,
2439 FL("cfg80211_vendor_event_alloc failed"));
2440 return;
2441 }
2442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2443 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2445 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2446
2447 for (i = 0; i < pData->numOfAps; i++) {
2448 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2449 "Ssid (%s) "
2450 "Bssid (" MAC_ADDRESS_STR ") "
2451 "Channel (%u) "
2452 "Rssi (%d) "
2453 "RTT (%u) "
2454 "RTT_SD (%u) ",
2455 i,
2456 pData->ap[i].ts,
2457 pData->ap[i].ssid,
2458 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2459 pData->ap[i].channel,
2460 pData->ap[i].rssi,
2461 pData->ap[i].rtt,
2462 pData->ap[i].rtt_sd);
2463 }
2464
2465 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2466 pData->requestId) ||
2467 nla_put_u32(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2469 pData->numOfAps)) {
2470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2471 goto fail;
2472 }
2473 if (pData->numOfAps) {
2474 struct nlattr *aps;
2475
2476 aps = nla_nest_start(skb,
2477 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2478 if (!aps)
2479 goto fail;
2480
2481 for (i = 0; i < pData->numOfAps; i++) {
2482 struct nlattr *ap;
2483
2484 ap = nla_nest_start(skb, i + 1);
2485 if (!ap)
2486 goto fail;
2487
2488 if (nla_put_u64(skb,
2489 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2490 pData->ap[i].ts) ||
2491 nla_put(skb,
2492 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2493 sizeof(pData->ap[i].ssid),
2494 pData->ap[i].ssid) ||
2495 nla_put(skb,
2496 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2497 sizeof(pData->ap[i].bssid),
2498 pData->ap[i].bssid) ||
2499 nla_put_u32(skb,
2500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2501 pData->ap[i].channel) ||
2502 nla_put_s32(skb,
2503 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2504 pData->ap[i].rssi) ||
2505 nla_put_u32(skb,
2506 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2507 pData->ap[i].rtt) ||
2508 nla_put_u32(skb,
2509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2510 pData->ap[i].rtt_sd))
2511 goto fail;
2512
2513 nla_nest_end(skb, ap);
2514 }
2515 nla_nest_end(skb, aps);
2516
2517 if (nla_put_u8(skb,
2518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2519 pData->moreData))
2520 goto fail;
2521 }
2522
2523 cfg80211_vendor_event(skb, GFP_KERNEL);
2524 return;
2525
2526fail:
2527 kfree_skb(skb);
2528 return;
2529
2530}
2531static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2532 void *pMsg)
2533{
2534 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2535 struct sk_buff *skb = NULL;
2536 tANI_U32 i, j;
2537 tpSirWifiSignificantChangeEvent pData =
2538 (tpSirWifiSignificantChangeEvent) pMsg;
2539
2540 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2542 "or pData(%p) is null"), pData);
2543 return;
2544 }
2545 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2546 EXTSCAN_EVENT_BUF_SIZE,
2547 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2548 GFP_KERNEL);
2549
2550 if (!skb) {
2551 hddLog(VOS_TRACE_LEVEL_ERROR,
2552 FL("cfg80211_vendor_event_alloc failed"));
2553 return;
2554 }
2555 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2556 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2557 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2558 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2559 pData->numSigRssiBss);
2560 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2561
2562 for (i = 0; i < pData->numSigRssiBss; i++) {
2563 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2564 " num RSSI %u ",
2565 i, pData->sigRssiResult[i].bssid,
2566 pData->sigRssiResult[i].channel,
2567 pData->sigRssiResult[i].numRssi);
2568
2569 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2570
2571 hddLog(VOS_TRACE_LEVEL_INFO,
2572 " [%d]",
2573 pData->sigRssiResult[i].rssi[0]);
2574
2575 }
2576 }
2577
2578
2579 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2580 pData->requestId) ||
2581 nla_put_u32(skb,
2582 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2583 pData->numSigRssiBss)) {
2584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2585 goto fail;
2586 }
2587
2588 if (pData->numSigRssiBss) {
2589 struct nlattr *aps;
2590 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2591 if (!aps)
2592 goto fail;
2593 for (i = 0; i < pData->numSigRssiBss; i++) {
2594 struct nlattr *ap;
2595
2596 ap = nla_nest_start(skb, i);
2597 if (!ap)
2598 goto fail;
2599 if (nla_put(skb,
2600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2601 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2602 nla_put_u32(skb,
2603 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2604 pData->sigRssiResult[i].channel) ||
2605 nla_put_u32(skb,
2606 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2607 pData->sigRssiResult[i].numRssi) ||
2608 nla_put(skb,
2609 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2610 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2611 pData->sigRssiResult[i].rssi))
2612 goto fail;
2613 nla_nest_end(skb, ap);
2614 }
2615 nla_nest_end(skb, aps);
2616 if (nla_put_u8(skb,
2617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2618 pData->moreData))
2619 goto fail;
2620 }
2621 cfg80211_vendor_event(skb, GFP_KERNEL);
2622 return;
2623fail:
2624 kfree_skb(skb);
2625 return;
2626}
2627
2628static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2629 void *pMsg)
2630{
2631 struct sk_buff *skb;
2632 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2633 tpSirWifiFullScanResultEvent pData =
2634 (tpSirWifiFullScanResultEvent) (pMsg);
2635
2636 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2638 "or pData(%p) is null"), pData);
2639 return;
2640 }
2641
2642 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2643 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2644 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2645 GFP_KERNEL);
2646
2647 if (!skb) {
2648 hddLog(VOS_TRACE_LEVEL_ERROR,
2649 FL("cfg80211_vendor_event_alloc failed"));
2650 return;
2651 }
2652
2653 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2655 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2657 "Ssid (%s)"
2658 "Bssid (" MAC_ADDRESS_STR ")"
2659 "Channel (%u)"
2660 "Rssi (%d)"
2661 "RTT (%u)"
2662 "RTT_SD (%u)"),
2663 pData->ap.ts,
2664 pData->ap.ssid,
2665 MAC_ADDR_ARRAY(pData->ap.bssid),
2666 pData->ap.channel,
2667 pData->ap.rssi,
2668 pData->ap.rtt,
2669 pData->ap.rtt_sd);
2670 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2671 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2672 pData->requestId) ||
2673 nla_put_u64(skb,
2674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2675 pData->ap.ts) ||
2676 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2677 sizeof(pData->ap.ssid),
2678 pData->ap.ssid) ||
2679 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2680 WNI_CFG_BSSID_LEN,
2681 pData->ap.bssid) ||
2682 nla_put_u32(skb,
2683 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2684 pData->ap.channel) ||
2685 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2686 pData->ap.rssi) ||
2687 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2688 pData->ap.rtt) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2691 pData->ap.rtt_sd) ||
2692 nla_put_u16(skb,
2693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2694 pData->ap.beaconPeriod) ||
2695 nla_put_u16(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2697 pData->ap.capability) ||
2698 nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2700 pData->ieLength))
2701 {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2703 goto nla_put_failure;
2704 }
2705 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2706 pData->ieLength,
2707 pData->ie))
2708 {
2709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2710 goto nla_put_failure;
2711 }
2712
2713 cfg80211_vendor_event(skb, GFP_KERNEL);
2714 return;
2715
2716nla_put_failure:
2717 kfree_skb(skb);
2718 return;
2719}
2720
2721static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2722 void *pMsg)
2723{
2724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2725 struct sk_buff *skb = NULL;
2726 tpSirEXTScanResultsAvailableIndParams pData =
2727 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2728
2729 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2731 "or pData(%p) is null"), pData);
2732 return;
2733 }
2734
2735 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2736 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2737 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2738 GFP_KERNEL);
2739
2740 if (!skb) {
2741 hddLog(VOS_TRACE_LEVEL_ERROR,
2742 FL("cfg80211_vendor_event_alloc failed"));
2743 return;
2744 }
2745
2746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2747 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2748 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2749 pData->numResultsAvailable);
2750 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2751 pData->requestId) ||
2752 nla_put_u32(skb,
2753 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2754 pData->numResultsAvailable)) {
2755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2756 goto nla_put_failure;
2757 }
2758
2759 cfg80211_vendor_event(skb, GFP_KERNEL);
2760 return;
2761
2762nla_put_failure:
2763 kfree_skb(skb);
2764 return;
2765}
2766
2767static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2768{
2769 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2770 struct sk_buff *skb = NULL;
2771 tpSirEXTScanProgressIndParams pData =
2772 (tpSirEXTScanProgressIndParams) pMsg;
2773
2774 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2776 "or pData(%p) is null"), pData);
2777 return;
2778 }
2779
2780 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2781 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2782 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2783 GFP_KERNEL);
2784
2785 if (!skb) {
2786 hddLog(VOS_TRACE_LEVEL_ERROR,
2787 FL("cfg80211_vendor_event_alloc failed"));
2788 return;
2789 }
2790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2791 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2792 pData->extScanEventType);
2793 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2794 pData->status);
2795
2796 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2797 pData->extScanEventType) ||
2798 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302799 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2800 pData->requestId) ||
2801 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2803 pData->status)) {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2805 goto nla_put_failure;
2806 }
2807
2808 cfg80211_vendor_event(skb, GFP_KERNEL);
2809 return;
2810
2811nla_put_failure:
2812 kfree_skb(skb);
2813 return;
2814}
2815
2816void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2817 void *pMsg)
2818{
2819 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2820
2821 if (wlan_hdd_validate_context(pHddCtx)) {
2822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2823 return;
2824 }
2825
2826 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2827
2828
2829 switch(evType) {
2830 case SIR_HAL_EXTSCAN_START_RSP:
2831 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2832 break;
2833
2834 case SIR_HAL_EXTSCAN_STOP_RSP:
2835 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2836 break;
2837 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2838 /* There is no need to send this response to upper layer
2839 Just log the message */
2840 hddLog(VOS_TRACE_LEVEL_INFO,
2841 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2842 break;
2843 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2844 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2845 break;
2846
2847 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2848 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2849 break;
2850
2851 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2852 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2853 break;
2854
2855 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2856 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2857 break;
2858 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2859 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2860 break;
2861 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2862 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2863 break;
2864 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2865 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2866 break;
2867 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2868 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2869 break;
2870 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2871 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2872 break;
2873 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2874 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2875 break;
2876 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2877 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2878 break;
2879 default:
2880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2881 break;
2882 }
2883}
2884
2885static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2886 struct wireless_dev *wdev,
2887 void *data, int dataLen)
2888{
2889 tpSirGetEXTScanCapabilitiesReqParams pReqMsg = NULL;
2890 struct net_device *dev = wdev->netdev;
2891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2893 struct nlattr
2894 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2895 eHalStatus status;
2896
2897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2898 status = wlan_hdd_validate_context(pHddCtx);
2899 if (0 != status)
2900 {
2901 hddLog(VOS_TRACE_LEVEL_ERROR,
2902 FL("HDD context is not valid"));
2903 return -EINVAL;
2904 }
2905 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2906 data, dataLen,
2907 wlan_hdd_extscan_config_policy)) {
2908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2909 return -EINVAL;
2910 }
2911
2912 /* Parse and fetch request Id */
2913 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2915 return -EINVAL;
2916 }
2917
2918 pReqMsg = (tpSirGetEXTScanCapabilitiesReqParams)
2919 vos_mem_malloc(sizeof(*pReqMsg));
2920 if (!pReqMsg) {
2921 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2922 return -ENOMEM;
2923 }
2924
2925 pReqMsg->requestId = nla_get_u32(
2926 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2927 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2928
2929 pReqMsg->sessionId = pAdapter->sessionId;
2930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2931
2932 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, pReqMsg);
2933 if (!HAL_STATUS_SUCCESS(status)) {
2934 hddLog(VOS_TRACE_LEVEL_ERROR,
2935 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
2936 vos_mem_free(pReqMsg);
2937 return -EINVAL;
2938 }
2939
2940 return 0;
2941}
2942
2943
2944static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2945 struct wireless_dev *wdev,
2946 void *data, int dataLen)
2947{
2948 tpSirEXTScanGetCachedResultsReqParams pReqMsg = NULL;
2949 struct net_device *dev = wdev->netdev;
2950 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2951 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2952 struct nlattr
2953 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2954 eHalStatus status;
2955
2956 status = wlan_hdd_validate_context(pHddCtx);
2957 if (0 != status)
2958 {
2959 hddLog(VOS_TRACE_LEVEL_ERROR,
2960 FL("HDD context is not valid"));
2961 return -EINVAL;
2962 }
2963 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2964 data, dataLen,
2965 wlan_hdd_extscan_config_policy)) {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2967 return -EINVAL;
2968 }
2969 /* Parse and fetch request Id */
2970 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2972 return -EINVAL;
2973 }
2974 pReqMsg = (tpSirEXTScanGetCachedResultsReqParams)
2975 vos_mem_malloc(sizeof(*pReqMsg));
2976 if (!pReqMsg) {
2977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2978 return -ENOMEM;
2979 }
2980
2981 pReqMsg->requestId = nla_get_u32(
2982 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2983
2984 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2985
2986 pReqMsg->sessionId = pAdapter->sessionId;
2987 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2988
2989 /* Parse and fetch flush parameter */
2990 if (!tb
2991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2992 {
2993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2994 goto failed;
2995 }
2996 pReqMsg->flush = nla_get_u8(
2997 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
2998
2999 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), pReqMsg->flush);
3000
3001 status = sme_getCachedResults(pHddCtx->hHal, pReqMsg);
3002 if (!HAL_STATUS_SUCCESS(status)) {
3003 hddLog(VOS_TRACE_LEVEL_ERROR,
3004 FL("sme_getCachedResults failed(err=%d)"), status);
3005 vos_mem_free(pReqMsg);
3006 return -EINVAL;
3007 }
3008 return 0;
3009
3010failed:
3011 vos_mem_free(pReqMsg);
3012 return -EINVAL;
3013}
3014
3015static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3016 struct wireless_dev *wdev,
3017 void *data, int dataLen)
3018{
3019 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3020 struct net_device *dev = wdev->netdev;
3021 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3022 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3023 struct nlattr
3024 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3025 struct nlattr
3026 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3027 struct nlattr *apTh;
3028 eHalStatus status;
3029 tANI_U8 i = 0;
3030 int rem;
3031
3032 status = wlan_hdd_validate_context(pHddCtx);
3033 if (0 != status)
3034 {
3035 hddLog(VOS_TRACE_LEVEL_ERROR,
3036 FL("HDD context is not valid"));
3037 return -EINVAL;
3038 }
3039 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3040 data, dataLen,
3041 wlan_hdd_extscan_config_policy)) {
3042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3043 return -EINVAL;
3044 }
3045
3046 /* Parse and fetch request Id */
3047 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3049 return -EINVAL;
3050 }
3051
3052 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3053 vos_mem_malloc(sizeof(*pReqMsg));
3054 if (!pReqMsg) {
3055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3056 return -ENOMEM;
3057 }
3058
3059 pReqMsg->requestId = nla_get_u32(
3060 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3061 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3062
3063 /* Parse and fetch number of APs */
3064 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3066 goto fail;
3067 }
3068
3069 pReqMsg->sessionId = pAdapter->sessionId;
3070 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3071
3072 pReqMsg->numAp = nla_get_u32(
3073 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3075
3076 nla_for_each_nested(apTh,
3077 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3078 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3079 nla_data(apTh), nla_len(apTh),
3080 NULL)) {
3081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3082 goto fail;
3083 }
3084
3085 /* Parse and fetch MAC address */
3086 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3088 goto fail;
3089 }
3090 memcpy(pReqMsg->ap[i].bssid, nla_data(
3091 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3092 sizeof(tSirMacAddr));
3093 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3094
3095 /* Parse and fetch low RSSI */
3096 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3098 goto fail;
3099 }
3100 pReqMsg->ap[i].low = nla_get_s32(
3101 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3102 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3103
3104 /* Parse and fetch high RSSI */
3105 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3107 goto fail;
3108 }
3109 pReqMsg->ap[i].high = nla_get_s32(
3110 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3111 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3112 pReqMsg->ap[i].high);
3113
3114 /* Parse and fetch channel */
3115 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3117 goto fail;
3118 }
3119 pReqMsg->ap[i].channel = nla_get_u32(
3120 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3121 hddLog(VOS_TRACE_LEVEL_INFO,
3122 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3123 i++;
3124 }
3125 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3126 if (!HAL_STATUS_SUCCESS(status)) {
3127 hddLog(VOS_TRACE_LEVEL_ERROR,
3128 FL("sme_SetBssHotlist failed(err=%d)"), status);
3129 vos_mem_free(pReqMsg);
3130 return -EINVAL;
3131 }
3132
3133 return 0;
3134
3135fail:
3136 vos_mem_free(pReqMsg);
3137 return -EINVAL;
3138}
3139
3140static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3141 struct wireless_dev *wdev,
3142 void *data, int dataLen)
3143{
3144 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3145 struct net_device *dev = wdev->netdev;
3146 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3147 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3148 struct nlattr
3149 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3150 struct nlattr
3151 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3152 struct nlattr *apTh;
3153 eHalStatus status;
3154 int i = 0;
3155 int rem;
3156
3157 status = wlan_hdd_validate_context(pHddCtx);
3158 if (0 != status)
3159 {
3160 hddLog(VOS_TRACE_LEVEL_ERROR,
3161 FL("HDD context is not valid"));
3162 return -EINVAL;
3163 }
3164 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3165 data, dataLen,
3166 wlan_hdd_extscan_config_policy)) {
3167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3168 return -EINVAL;
3169 }
3170
3171 /* Parse and fetch request Id */
3172 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3174 return -EINVAL;
3175 }
3176
3177 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
3178 vos_mem_malloc(sizeof(*pReqMsg));
3179 if (!pReqMsg) {
3180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3181 return -ENOMEM;
3182 }
3183
3184 pReqMsg->requestId = nla_get_u32(
3185 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3186 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3187
3188 /* Parse and fetch RSSI sample size */
3189 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3190 {
3191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3192 goto fail;
3193 }
3194 pReqMsg->rssiSampleSize = nla_get_u32(
3195 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3196 hddLog(VOS_TRACE_LEVEL_INFO,
3197 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3198
3199 /* Parse and fetch lost AP sample size */
3200 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3201 {
3202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3203 goto fail;
3204 }
3205 pReqMsg->lostApSampleSize = nla_get_u32(
3206 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3207 hddLog(VOS_TRACE_LEVEL_INFO,
3208 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3209 /* Parse and fetch minimum Breaching */
3210 if (!tb
3211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3213 goto fail;
3214 }
3215 pReqMsg->minBreaching = nla_get_u32(
3216 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3217 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3218
3219 /* Parse and fetch number of APs */
3220 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3221 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3222 goto fail;
3223 }
3224 pReqMsg->numAp = nla_get_u32(
3225 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3226 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3227
3228 pReqMsg->sessionId = pAdapter->sessionId;
3229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3230
3231 nla_for_each_nested(apTh,
3232 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3233 if(nla_parse(tb2,
3234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3235 nla_data(apTh), nla_len(apTh),
3236 NULL)) {
3237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3238 goto fail;
3239 }
3240
3241 /* Parse and fetch MAC address */
3242 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3244 goto fail;
3245 }
3246 memcpy(pReqMsg->ap[i].bssid, nla_data(
3247 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3248 sizeof(tSirMacAddr));
3249
3250 /* Parse and fetch low RSSI */
3251 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3253 goto fail;
3254 }
3255 pReqMsg->ap[i].low = nla_get_s32(
3256 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3257 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3258
3259 /* Parse and fetch high RSSI */
3260 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3262 goto fail;
3263 }
3264 pReqMsg->ap[i].high = nla_get_s32(
3265 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3266 hddLog(VOS_TRACE_LEVEL_INFO,
3267 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3268
3269 /* Parse and fetch channel */
3270 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3272 goto fail;
3273 }
3274 pReqMsg->ap[i].channel = nla_get_u32(
3275 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3276 hddLog(VOS_TRACE_LEVEL_INFO,
3277 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3278 i++;
3279 }
3280
3281 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3282 if (!HAL_STATUS_SUCCESS(status)) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 FL("sme_SetSignificantChange failed(err=%d)"), status);
3285 vos_mem_free(pReqMsg);
3286 return -EINVAL;
3287 }
3288
3289 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3290 return 0;
3291
3292fail:
3293 vos_mem_free(pReqMsg);
3294 return -EINVAL;
3295}
3296
3297static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3298 struct wireless_dev *wdev,
3299 void *data, int dataLen)
3300{
3301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3302 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3303 tANI_U8 numChannels = 0;
3304 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3305 tANI_U32 requestId;
3306 tWifiBand wifiBand;
3307 eHalStatus status;
3308 struct sk_buff *replySkb;
3309 tANI_U8 i;
3310
3311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3312 status = wlan_hdd_validate_context(pHddCtx);
3313 if (0 != status)
3314 {
3315 hddLog(VOS_TRACE_LEVEL_ERROR,
3316 FL("HDD context is not valid"));
3317 return -EINVAL;
3318 }
3319 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3320 data, dataLen,
3321 wlan_hdd_extscan_config_policy)) {
3322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3323 return -EINVAL;
3324 }
3325
3326 /* Parse and fetch request Id */
3327 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3329 return -EINVAL;
3330 }
3331 requestId = nla_get_u32(
3332 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3333 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3334
3335 /* Parse and fetch wifi band */
3336 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3337 {
3338 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3339 return -EINVAL;
3340 }
3341 wifiBand = nla_get_u32(
3342 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3343 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3344
3345 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3346 wifiBand, ChannelList,
3347 &numChannels);
3348 if (eHAL_STATUS_SUCCESS != status) {
3349 hddLog(VOS_TRACE_LEVEL_ERROR,
3350 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3351 return -EINVAL;
3352 }
3353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3354 for (i = 0; i < numChannels; i++)
3355 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3356
3357 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3358 sizeof(u32) * numChannels +
3359 NLMSG_HDRLEN);
3360
3361 if (!replySkb) {
3362 hddLog(VOS_TRACE_LEVEL_ERROR,
3363 FL("valid channels: buffer alloc fail"));
3364 return -EINVAL;
3365 }
3366 if (nla_put_u32(replySkb,
3367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3368 numChannels) ||
3369 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3370 sizeof(u32) * numChannels, ChannelList)) {
3371
3372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3373 kfree_skb(replySkb);
3374 return -EINVAL;
3375 }
3376
3377 return cfg80211_vendor_cmd_reply(replySkb);
3378}
3379
3380static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3381 struct wireless_dev *wdev,
3382 void *data, int dataLen)
3383{
3384 tpSirEXTScanStartReqParams pReqMsg = NULL;
3385 struct net_device *dev = wdev->netdev;
3386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3387 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3388 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3389 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3390 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3391 struct nlattr *buckets;
3392 struct nlattr *channels;
3393 int rem1;
3394 int rem2;
3395 eHalStatus status;
3396 tANI_U8 bktIndex;
3397 tANI_U32 i = 0, j = 0;
3398
3399 status = wlan_hdd_validate_context(pHddCtx);
3400 if (0 != status)
3401 {
3402 hddLog(VOS_TRACE_LEVEL_ERROR,
3403 FL("HDD context is not valid"));
3404 return -EINVAL;
3405 }
3406 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3407 data, dataLen,
3408 wlan_hdd_extscan_config_policy)) {
3409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3410 return -EINVAL;
3411 }
3412
3413 /* Parse and fetch request Id */
3414 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3416 return -EINVAL;
3417 }
3418
3419 pReqMsg = (tpSirEXTScanStartReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3420 if (!pReqMsg) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3422 return -ENOMEM;
3423 }
3424
3425 pReqMsg->requestId = nla_get_u32(
3426 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3427 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3428
3429 pReqMsg->sessionId = pAdapter->sessionId;
3430 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3431
3432 /* Parse and fetch base period */
3433 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3435 goto fail;
3436 }
3437 pReqMsg->basePeriod = nla_get_u32(
3438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3439 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3440 pReqMsg->basePeriod);
3441
3442 /* Parse and fetch max AP per scan */
3443 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3445 goto fail;
3446 }
3447 pReqMsg->maxAPperScan = nla_get_u32(
3448 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3449 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3450 pReqMsg->maxAPperScan);
3451
3452 /* Parse and fetch report threshold */
3453 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3455 goto fail;
3456 }
3457 pReqMsg->reportThreshold = nla_get_u8(
3458 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3459 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3460 pReqMsg->reportThreshold);
3461
3462 /* Parse and fetch number of buckets */
3463 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3465 goto fail;
3466 }
3467 pReqMsg->numBuckets = nla_get_u8(
3468 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3469 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3470 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3471 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3472 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3473 }
3474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3475 pReqMsg->numBuckets);
3476 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3478 goto fail;
3479 }
3480
3481 nla_for_each_nested(buckets,
3482 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3483 if(nla_parse(bucket,
3484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3485 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3487 goto fail;
3488 }
3489
3490 /* Parse and fetch bucket spec */
3491 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3493 goto fail;
3494 }
3495 bktIndex = nla_get_u8(
3496 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3497 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3498 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3499
3500 /* Parse and fetch wifi band */
3501 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3503 goto fail;
3504 }
3505 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3506 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3507 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3508 pReqMsg->buckets[bktIndex].band);
3509
3510 /* Parse and fetch period */
3511 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3513 goto fail;
3514 }
3515 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3516 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3517 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3518 pReqMsg->buckets[bktIndex].period);
3519
3520 /* Parse and fetch report events */
3521 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3523 goto fail;
3524 }
3525 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3526 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3528 pReqMsg->buckets[bktIndex].reportEvents);
3529
3530 /* Parse and fetch number of channels */
3531 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3533 goto fail;
3534 }
3535 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3536 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3537 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3538 pReqMsg->buckets[bktIndex].numChannels);
3539
3540 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3542 goto fail;
3543 }
3544
3545 j = 0;
3546 nla_for_each_nested(channels,
3547 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3548 if(nla_parse(channel,
3549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3550 nla_data(channels), nla_len(channels),
3551 NULL)) { //wlan_hdd_extscan_config_policy here
3552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3553 goto fail;
3554 }
3555
3556 /* Parse and fetch channel */
3557 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3559 goto fail;
3560 }
3561 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3562 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3563 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3564 pReqMsg->buckets[bktIndex].channels[j].channel);
3565
3566 /* Parse and fetch dwell time */
3567 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3569 goto fail;
3570 }
3571 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3572 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3573 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3574 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3575
3576 /* Parse and fetch channel spec passive */
3577 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3578 hddLog(VOS_TRACE_LEVEL_ERROR,
3579 FL("attr channel spec passive failed"));
3580 goto fail;
3581 }
3582 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3583 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3584 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3585 pReqMsg->buckets[bktIndex].channels[j].passive);
3586 j++;
3587 }
3588 i++;
3589 }
3590 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3591 if (!HAL_STATUS_SUCCESS(status)) {
3592 hddLog(VOS_TRACE_LEVEL_ERROR,
3593 FL("sme_EXTScanStart failed(err=%d)"), status);
3594 vos_mem_free(pReqMsg);
3595 return -EINVAL;
3596 }
3597
3598 return 0;
3599
3600fail:
3601 vos_mem_free(pReqMsg);
3602 return -EINVAL;
3603}
3604
3605static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3606 struct wireless_dev *wdev,
3607 void *data, int dataLen)
3608{
3609 tpSirEXTScanStopReqParams pReqMsg = NULL;
3610 struct net_device *dev = wdev->netdev;
3611 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3612 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3613 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3614 eHalStatus status;
3615
3616 status = wlan_hdd_validate_context(pHddCtx);
3617 if (0 != status)
3618 {
3619 hddLog(VOS_TRACE_LEVEL_ERROR,
3620 FL("HDD context is not valid"));
3621 return -EINVAL;
3622 }
3623 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3624 data, dataLen,
3625 wlan_hdd_extscan_config_policy)) {
3626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3627 return -EINVAL;
3628 }
3629
3630 /* Parse and fetch request Id */
3631 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3633 return -EINVAL;
3634 }
3635
3636 pReqMsg = (tpSirEXTScanStopReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3637 if (!pReqMsg) {
3638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3639 return -ENOMEM;
3640 }
3641
3642 pReqMsg->requestId = nla_get_u32(
3643 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3644 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3645
3646 pReqMsg->sessionId = pAdapter->sessionId;
3647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3648
3649 status = sme_EXTScanStop(pHddCtx->hHal, pReqMsg);
3650 if (!HAL_STATUS_SUCCESS(status)) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR,
3652 FL("sme_EXTScanStop failed(err=%d)"), status);
3653 vos_mem_free(pReqMsg);
3654 return -EINVAL;
3655 }
3656
3657 return 0;
3658}
3659
3660static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3661 struct wireless_dev *wdev,
3662 void *data, int dataLen)
3663{
3664 tpSirEXTScanResetBssidHotlistReqParams pReqMsg = NULL;
3665 struct net_device *dev = wdev->netdev;
3666 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3667 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3668 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3669 eHalStatus status;
3670
3671 status = wlan_hdd_validate_context(pHddCtx);
3672 if (0 != status)
3673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR,
3675 FL("HDD context is not valid"));
3676 return -EINVAL;
3677 }
3678 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3679 data, dataLen,
3680 wlan_hdd_extscan_config_policy)) {
3681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3682 return -EINVAL;
3683 }
3684
3685 /* Parse and fetch request Id */
3686 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3688 return -EINVAL;
3689 }
3690
3691 pReqMsg = (tpSirEXTScanResetBssidHotlistReqParams)
3692 vos_mem_malloc(sizeof(*pReqMsg));
3693 if (!pReqMsg) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3695 return -ENOMEM;
3696 }
3697
3698 pReqMsg->requestId = nla_get_u32(
3699 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3700 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3701
3702 pReqMsg->sessionId = pAdapter->sessionId;
3703 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3704
3705 status = sme_ResetBssHotlist(pHddCtx->hHal, pReqMsg);
3706 if (!HAL_STATUS_SUCCESS(status)) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR,
3708 FL("sme_ResetBssHotlist failed(err=%d)"), status);
3709 vos_mem_free(pReqMsg);
3710 return -EINVAL;
3711 }
3712
3713 return 0;
3714}
3715
3716static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3717 struct wiphy *wiphy,
3718 struct wireless_dev *wdev,
3719 void *data, int dataLen)
3720{
3721 tpSirEXTScanResetSignificantChangeReqParams pReqMsg = NULL;
3722 struct net_device *dev = wdev->netdev;
3723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3724 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3725 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3726 eHalStatus status;
3727
3728 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3729 status = wlan_hdd_validate_context(pHddCtx);
3730 if (0 != status)
3731 {
3732 hddLog(VOS_TRACE_LEVEL_ERROR,
3733 FL("HDD context is not valid"));
3734 return -EINVAL;
3735 }
3736 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3737 data, dataLen,
3738 wlan_hdd_extscan_config_policy)) {
3739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3740 return -EINVAL;
3741 }
3742
3743 /* Parse and fetch request Id */
3744 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3746 return -EINVAL;
3747 }
3748
3749 pReqMsg = (tpSirEXTScanResetSignificantChangeReqParams)
3750 vos_mem_malloc(sizeof(*pReqMsg));
3751 if (!pReqMsg) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3753 return -ENOMEM;
3754 }
3755
3756 pReqMsg->requestId = nla_get_u32(
3757 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3758 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3759
3760 pReqMsg->sessionId = pAdapter->sessionId;
3761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3762
3763 status = sme_ResetSignificantChange(pHddCtx->hHal, pReqMsg);
3764 if (!HAL_STATUS_SUCCESS(status)) {
3765 hddLog(VOS_TRACE_LEVEL_ERROR,
3766 FL("sme_ResetSignificantChange failed(err=%d)"), status);
3767 vos_mem_free(pReqMsg);
3768 return -EINVAL;
3769 }
3770
3771 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3772 return 0;
3773}
3774
3775#endif /* WLAN_FEATURE_EXTSCAN */
3776
Sunil Duttc69bccb2014-05-26 21:30:20 +05303777const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3778{
3779#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3780 {
3781 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3782 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3783 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3784 WIPHY_VENDOR_CMD_NEED_NETDEV |
3785 WIPHY_VENDOR_CMD_NEED_RUNNING,
3786 .doit = wlan_hdd_cfg80211_ll_stats_clear
3787 },
3788
3789 {
3790 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3791 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3792 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3793 WIPHY_VENDOR_CMD_NEED_NETDEV |
3794 WIPHY_VENDOR_CMD_NEED_RUNNING,
3795 .doit = wlan_hdd_cfg80211_ll_stats_set
3796 },
3797
3798 {
3799 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3800 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3801 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3802 WIPHY_VENDOR_CMD_NEED_NETDEV |
3803 WIPHY_VENDOR_CMD_NEED_RUNNING,
3804 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303806#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303807#ifdef WLAN_FEATURE_EXTSCAN
3808 {
3809 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3810 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3811 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3812 WIPHY_VENDOR_CMD_NEED_NETDEV |
3813 WIPHY_VENDOR_CMD_NEED_RUNNING,
3814 .doit = wlan_hdd_cfg80211_extscan_start
3815 },
3816 {
3817 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3818 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3819 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3820 WIPHY_VENDOR_CMD_NEED_NETDEV |
3821 WIPHY_VENDOR_CMD_NEED_RUNNING,
3822 .doit = wlan_hdd_cfg80211_extscan_stop
3823 },
3824 {
3825 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3826 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3827 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3828 WIPHY_VENDOR_CMD_NEED_NETDEV,
3829 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3830 },
3831 {
3832 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3833 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3834 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3835 WIPHY_VENDOR_CMD_NEED_NETDEV |
3836 WIPHY_VENDOR_CMD_NEED_RUNNING,
3837 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3838 },
3839 {
3840 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3841 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3842 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3843 WIPHY_VENDOR_CMD_NEED_NETDEV |
3844 WIPHY_VENDOR_CMD_NEED_RUNNING,
3845 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3846 },
3847 {
3848 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3849 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3850 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3851 WIPHY_VENDOR_CMD_NEED_NETDEV |
3852 WIPHY_VENDOR_CMD_NEED_RUNNING,
3853 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3854 },
3855 {
3856 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3857 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3858 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3859 WIPHY_VENDOR_CMD_NEED_NETDEV |
3860 WIPHY_VENDOR_CMD_NEED_RUNNING,
3861 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3862 },
3863 {
3864 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3865 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3866 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3867 WIPHY_VENDOR_CMD_NEED_NETDEV |
3868 WIPHY_VENDOR_CMD_NEED_RUNNING,
3869 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3870 },
3871 {
3872 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3873 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3874 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3875 WIPHY_VENDOR_CMD_NEED_NETDEV |
3876 WIPHY_VENDOR_CMD_NEED_RUNNING,
3877 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3878 },
3879#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303880};
3881
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003882/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303883static const
3884struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003885{
3886#ifdef FEATURE_WLAN_CH_AVOID
3887 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303888 .vendor_id = QCA_NL80211_VENDOR_ID,
3889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003890 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303891#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3892#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3893 {
3894 /* Index = 1*/
3895 .vendor_id = QCA_NL80211_VENDOR_ID,
3896 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3897 },
3898 {
3899 /* Index = 2*/
3900 .vendor_id = QCA_NL80211_VENDOR_ID,
3901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3902 },
3903 {
3904 /* Index = 3*/
3905 .vendor_id = QCA_NL80211_VENDOR_ID,
3906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3907 },
3908 {
3909 /* Index = 4*/
3910 .vendor_id = QCA_NL80211_VENDOR_ID,
3911 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3912 },
3913 {
3914 /* Index = 5*/
3915 .vendor_id = QCA_NL80211_VENDOR_ID,
3916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3917 },
3918 {
3919 /* Index = 6*/
3920 .vendor_id = QCA_NL80211_VENDOR_ID,
3921 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3922 },
3923#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924#ifdef WLAN_FEATURE_EXTSCAN
3925 {
3926 .vendor_id = QCA_NL80211_VENDOR_ID,
3927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3928 },
3929 {
3930 .vendor_id = QCA_NL80211_VENDOR_ID,
3931 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3932 },
3933 {
3934 .vendor_id = QCA_NL80211_VENDOR_ID,
3935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3936 },
3937 {
3938 .vendor_id = QCA_NL80211_VENDOR_ID,
3939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3940 },
3941 {
3942 .vendor_id = QCA_NL80211_VENDOR_ID,
3943 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3944 },
3945 {
3946 .vendor_id = QCA_NL80211_VENDOR_ID,
3947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3948 },
3949 {
3950 .vendor_id = QCA_NL80211_VENDOR_ID,
3951 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
3952 },
3953 {
3954 .vendor_id = QCA_NL80211_VENDOR_ID,
3955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
3956 },
3957 {
3958 .vendor_id = QCA_NL80211_VENDOR_ID,
3959 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
3960 },
3961 {
3962 .vendor_id = QCA_NL80211_VENDOR_ID,
3963 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
3964 },
3965 {
3966 .vendor_id = QCA_NL80211_VENDOR_ID,
3967 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
3968 },
3969 {
3970 .vendor_id = QCA_NL80211_VENDOR_ID,
3971 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
3972 },
3973 {
3974 .vendor_id = QCA_NL80211_VENDOR_ID,
3975 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
3976 },
3977#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303978
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003979};
3980
Jeff Johnson295189b2012-06-20 16:38:30 -07003981/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303982 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303983 * This function is called by hdd_wlan_startup()
3984 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303985 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303987struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07003988{
3989 struct wiphy *wiphy;
3990 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303991 /*
3992 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 */
3994 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
3995
3996 if (!wiphy)
3997 {
3998 /* Print error and jump into err label and free the memory */
3999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4000 return NULL;
4001 }
4002
Sunil Duttc69bccb2014-05-26 21:30:20 +05304003
Jeff Johnson295189b2012-06-20 16:38:30 -07004004 return wiphy;
4005}
4006
4007/*
4008 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304009 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004010 * private ioctl to change the band value
4011 */
4012int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4013{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304014 int i, j;
4015 eNVChannelEnabledType channelEnabledState;
4016
Jeff Johnsone7245742012-09-05 17:12:55 -07004017 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304018
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304019 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004020 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304021
4022 if (NULL == wiphy->bands[i])
4023 {
4024 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4025 __func__, i);
4026 continue;
4027 }
4028
4029 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4030 {
4031 struct ieee80211_supported_band *band = wiphy->bands[i];
4032
4033 channelEnabledState = vos_nv_getChannelEnabledState(
4034 band->channels[j].hw_value);
4035
4036 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4037 {
4038 // Enable Social channels for P2P
4039 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4040 NV_CHANNEL_ENABLE == channelEnabledState)
4041 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4042 else
4043 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4044 continue;
4045 }
4046 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4047 {
4048 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4049 continue;
4050 }
4051
4052 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4053 NV_CHANNEL_INVALID == channelEnabledState)
4054 {
4055 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4056 }
4057 else if (NV_CHANNEL_DFS == channelEnabledState)
4058 {
4059 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4060 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4061 }
4062 else
4063 {
4064 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4065 |IEEE80211_CHAN_RADAR);
4066 }
4067 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004068 }
4069 return 0;
4070}
4071/*
4072 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304073 * This function is called by hdd_wlan_startup()
4074 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 * This function is used to initialize and register wiphy structure.
4076 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304077int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004078 struct wiphy *wiphy,
4079 hdd_config_t *pCfg
4080 )
4081{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304082 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4084
Jeff Johnsone7245742012-09-05 17:12:55 -07004085 ENTER();
4086
Jeff Johnson295189b2012-06-20 16:38:30 -07004087 /* Now bind the underlying wlan device with wiphy */
4088 set_wiphy_dev(wiphy, dev);
4089
4090 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004091
Kiet Lam6c583332013-10-14 05:37:09 +05304092#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004093 /* the flag for the other case would be initialzed in
4094 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004095 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304096#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004097
Amar Singhalfddc28c2013-09-05 13:03:40 -07004098 /* This will disable updating of NL channels from passive to
4099 * active if a beacon is received on passive channel. */
4100 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004101
Amar Singhalfddc28c2013-09-05 13:03:40 -07004102
Amar Singhala49cbc52013-10-08 18:37:44 -07004103
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004105 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4106 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4107 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004108 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304109 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004110#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004111
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004112#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004113 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004114#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004115 || pCfg->isFastRoamIniFeatureEnabled
4116#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004117#ifdef FEATURE_WLAN_ESE
4118 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004119#endif
4120 )
4121 {
4122 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4123 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004124#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004125#ifdef FEATURE_WLAN_TDLS
4126 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4127 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4128#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304129#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304130 if (pCfg->configPNOScanSupport)
4131 {
4132 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4133 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4134 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4135 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4136 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304137#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004138
Amar Singhalfddc28c2013-09-05 13:03:40 -07004139#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004140 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4141 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004142 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004143 driver need to determine what to do with both
4144 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004145
4146 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004147#else
4148 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004149#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304151 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4152
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304153 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004154
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304155 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4156
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304158 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004159 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4161 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004162 | BIT(NL80211_IFTYPE_AP);
4163
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304164 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004165 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4167 if( pCfg->enableMCC )
4168 {
4169 /* Currently, supports up to two channels */
4170 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004171
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304172 if( !pCfg->allowMCCGODiffBI )
4173 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004174
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304175 }
4176 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4177 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004178#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304179 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004180
Jeff Johnson295189b2012-06-20 16:38:30 -07004181 /* Before registering we need to update the ht capabilitied based
4182 * on ini values*/
4183 if( !pCfg->ShortGI20MhzEnable )
4184 {
4185 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4186 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4187 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4188 }
4189
4190 if( !pCfg->ShortGI40MhzEnable )
4191 {
4192 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4193 }
4194
4195 if( !pCfg->nChannelBondingMode5GHz )
4196 {
4197 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4198 }
4199
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304200 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304201 if (true == hdd_is_5g_supported(pHddCtx))
4202 {
4203 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4204 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304205
4206 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4207 {
4208
4209 if (NULL == wiphy->bands[i])
4210 {
4211 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4212 __func__, i);
4213 continue;
4214 }
4215
4216 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4217 {
4218 struct ieee80211_supported_band *band = wiphy->bands[i];
4219
4220 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4221 {
4222 // Enable social channels for P2P
4223 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4224 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4225 else
4226 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4227 continue;
4228 }
4229 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4230 {
4231 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4232 continue;
4233 }
4234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 }
4236 /*Initialise the supported cipher suite details*/
4237 wiphy->cipher_suites = hdd_cipher_suites;
4238 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4239
4240 /*signal strength in mBm (100*dBm) */
4241 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4242
4243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07004244 wiphy->max_remain_on_channel_duration = 1000;
4245#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004246
Sunil Duttc69bccb2014-05-26 21:30:20 +05304247 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4248 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004249 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4250 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4251
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304252 EXIT();
4253 return 0;
4254}
4255
4256/* In this function we are registering wiphy. */
4257int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4258{
4259 ENTER();
4260 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004261 if (0 > wiphy_register(wiphy))
4262 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304263 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004264 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4265 return -EIO;
4266 }
4267
4268 EXIT();
4269 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304270}
Jeff Johnson295189b2012-06-20 16:38:30 -07004271
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304272/* In this function we are updating channel list when,
4273 regulatory domain is FCC and country code is US.
4274 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4275 As per FCC smart phone is not a indoor device.
4276 GO should not opeate on indoor channels */
4277void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4278{
4279 int j;
4280 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4281 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4282 //Default counrtycode from NV at the time of wiphy initialization.
4283 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4284 &defaultCountryCode[0]))
4285 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004286 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304287 }
4288 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4289 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304290 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4291 {
4292 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4293 return;
4294 }
4295 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4296 {
4297 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4298 // Mark UNII -1 band channel as passive
4299 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4300 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4301 }
4302 }
4303}
4304
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304305/* This function registers for all frame which supplicant is interested in */
4306void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004307{
Jeff Johnson295189b2012-06-20 16:38:30 -07004308 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4309 /* Register for all P2P action, public action etc frames */
4310 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4311
Jeff Johnsone7245742012-09-05 17:12:55 -07004312 ENTER();
4313
Jeff Johnson295189b2012-06-20 16:38:30 -07004314 /* Right now we are registering these frame when driver is getting
4315 initialized. Once we will move to 2.6.37 kernel, in which we have
4316 frame register ops, we will move this code as a part of that */
4317 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304318 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004319 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4320
4321 /* GAS Initial Response */
4322 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4323 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304324
Jeff Johnson295189b2012-06-20 16:38:30 -07004325 /* GAS Comeback Request */
4326 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4327 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4328
4329 /* GAS Comeback Response */
4330 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4331 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4332
4333 /* P2P Public Action */
4334 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004336 P2P_PUBLIC_ACTION_FRAME_SIZE );
4337
4338 /* P2P Action */
4339 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4340 (v_U8_t*)P2P_ACTION_FRAME,
4341 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004342
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304343 /* WNM BSS Transition Request frame */
4344 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4345 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4346 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004347
4348 /* WNM-Notification */
4349 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4350 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4351 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004352}
4353
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304354void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004355{
Jeff Johnson295189b2012-06-20 16:38:30 -07004356 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4357 /* Register for all P2P action, public action etc frames */
4358 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4359
Jeff Johnsone7245742012-09-05 17:12:55 -07004360 ENTER();
4361
Jeff Johnson295189b2012-06-20 16:38:30 -07004362 /* Right now we are registering these frame when driver is getting
4363 initialized. Once we will move to 2.6.37 kernel, in which we have
4364 frame register ops, we will move this code as a part of that */
4365 /* GAS Initial Request */
4366
4367 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4368 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4369
4370 /* GAS Initial Response */
4371 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4372 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304373
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 /* GAS Comeback Request */
4375 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4376 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4377
4378 /* GAS Comeback Response */
4379 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4380 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4381
4382 /* P2P Public Action */
4383 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304384 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004385 P2P_PUBLIC_ACTION_FRAME_SIZE );
4386
4387 /* P2P Action */
4388 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4389 (v_U8_t*)P2P_ACTION_FRAME,
4390 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004391 /* WNM-Notification */
4392 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4393 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4394 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004395}
4396
4397#ifdef FEATURE_WLAN_WAPI
4398void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4399 const u8 *mac_addr, u8 *key , int key_Len)
4400{
4401 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4402 tCsrRoamSetKey setKey;
4403 v_BOOL_t isConnected = TRUE;
4404 int status = 0;
4405 v_U32_t roamId= 0xFF;
4406 tANI_U8 *pKeyPtr = NULL;
4407 int n = 0;
4408
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304409 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4410 __func__, hdd_device_modetoString(pAdapter->device_mode),
4411 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004412
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304413 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004414 setKey.keyId = key_index; // Store Key ID
4415 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4416 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4417 setKey.paeRole = 0 ; // the PAE role
4418 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4419 {
4420 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4421 }
4422 else
4423 {
4424 isConnected = hdd_connIsConnected(pHddStaCtx);
4425 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4426 }
4427 setKey.keyLength = key_Len;
4428 pKeyPtr = setKey.Key;
4429 memcpy( pKeyPtr, key, key_Len);
4430
Arif Hussain6d2a3322013-11-17 19:50:10 -08004431 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004432 __func__, key_Len);
4433 for (n = 0 ; n < key_Len; n++)
4434 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4435 __func__,n,setKey.Key[n]);
4436
4437 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4438 if ( isConnected )
4439 {
4440 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4441 pAdapter->sessionId, &setKey, &roamId );
4442 }
4443 if ( status != 0 )
4444 {
4445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4446 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4447 __LINE__, status );
4448 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4449 }
4450}
4451#endif /* FEATURE_WLAN_WAPI*/
4452
4453#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304454int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 beacon_data_t **ppBeacon,
4456 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004457#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304458int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004459 beacon_data_t **ppBeacon,
4460 struct cfg80211_beacon_data *params,
4461 int dtim_period)
4462#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304463{
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 int size;
4465 beacon_data_t *beacon = NULL;
4466 beacon_data_t *old = NULL;
4467 int head_len,tail_len;
4468
Jeff Johnsone7245742012-09-05 17:12:55 -07004469 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004470 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304471 {
4472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4473 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004474 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004476
4477 old = pAdapter->sessionCtx.ap.beacon;
4478
4479 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304480 {
4481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4482 FL("session(%d) old and new heads points to NULL"),
4483 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004484 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304485 }
4486
4487 if (params->tail && !params->tail_len)
4488 {
4489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4490 FL("tail_len is zero but tail is not NULL"));
4491 return -EINVAL;
4492 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004493
Jeff Johnson295189b2012-06-20 16:38:30 -07004494#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4495 /* Kernel 3.0 is not updating dtim_period for set beacon */
4496 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304497 {
4498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4499 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004500 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004502#endif
4503
4504 if(params->head)
4505 head_len = params->head_len;
4506 else
4507 head_len = old->head_len;
4508
4509 if(params->tail || !old)
4510 tail_len = params->tail_len;
4511 else
4512 tail_len = old->tail_len;
4513
4514 size = sizeof(beacon_data_t) + head_len + tail_len;
4515
4516 beacon = kzalloc(size, GFP_KERNEL);
4517
4518 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304519 {
4520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4521 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004522 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304523 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004524
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004525#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004526 if(params->dtim_period || !old )
4527 beacon->dtim_period = params->dtim_period;
4528 else
4529 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004530#else
4531 if(dtim_period || !old )
4532 beacon->dtim_period = dtim_period;
4533 else
4534 beacon->dtim_period = old->dtim_period;
4535#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304536
Jeff Johnson295189b2012-06-20 16:38:30 -07004537 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4538 beacon->tail = beacon->head + head_len;
4539 beacon->head_len = head_len;
4540 beacon->tail_len = tail_len;
4541
4542 if(params->head) {
4543 memcpy (beacon->head,params->head,beacon->head_len);
4544 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304545 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004546 if(old)
4547 memcpy (beacon->head,old->head,beacon->head_len);
4548 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304549
Jeff Johnson295189b2012-06-20 16:38:30 -07004550 if(params->tail) {
4551 memcpy (beacon->tail,params->tail,beacon->tail_len);
4552 }
4553 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304554 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 memcpy (beacon->tail,old->tail,beacon->tail_len);
4556 }
4557
4558 *ppBeacon = beacon;
4559
4560 kfree(old);
4561
4562 return 0;
4563
4564}
Jeff Johnson295189b2012-06-20 16:38:30 -07004565
4566v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4567{
4568 int left = length;
4569 v_U8_t *ptr = pIes;
4570 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304571
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304573 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004574 elem_id = ptr[0];
4575 elem_len = ptr[1];
4576 left -= 2;
4577 if(elem_len > left)
4578 {
4579 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004580 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004581 eid,elem_len,left);
4582 return NULL;
4583 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304584 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004585 {
4586 return ptr;
4587 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588
Jeff Johnson295189b2012-06-20 16:38:30 -07004589 left -= elem_len;
4590 ptr += (elem_len + 2);
4591 }
4592 return NULL;
4593}
4594
Jeff Johnson295189b2012-06-20 16:38:30 -07004595/* Check if rate is 11g rate or not */
4596static int wlan_hdd_rate_is_11g(u8 rate)
4597{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004598 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004599 u8 i;
4600 for (i = 0; i < 8; i++)
4601 {
4602 if(rate == gRateArray[i])
4603 return TRUE;
4604 }
4605 return FALSE;
4606}
4607
4608/* Check for 11g rate and set proper 11g only mode */
4609static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4610 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4611{
4612 u8 i, num_rates = pIe[0];
4613
4614 pIe += 1;
4615 for ( i = 0; i < num_rates; i++)
4616 {
4617 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4618 {
4619 /* If rate set have 11g rate than change the mode to 11G */
4620 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4621 if (pIe[i] & BASIC_RATE_MASK)
4622 {
4623 /* If we have 11g rate as basic rate, it means mode
4624 is 11g only mode.
4625 */
4626 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4627 *pCheckRatesfor11g = FALSE;
4628 }
4629 }
4630 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4631 {
4632 *require_ht = TRUE;
4633 }
4634 }
4635 return;
4636}
4637
4638static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4639{
4640 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4641 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4642 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4643 u8 checkRatesfor11g = TRUE;
4644 u8 require_ht = FALSE;
4645 u8 *pIe=NULL;
4646
4647 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4648
4649 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4650 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4651 if (pIe != NULL)
4652 {
4653 pIe += 1;
4654 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4655 &pConfig->SapHw_mode);
4656 }
4657
4658 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4659 WLAN_EID_EXT_SUPP_RATES);
4660 if (pIe != NULL)
4661 {
4662
4663 pIe += 1;
4664 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4665 &pConfig->SapHw_mode);
4666 }
4667
4668 if( pConfig->channel > 14 )
4669 {
4670 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4671 }
4672
4673 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4674 WLAN_EID_HT_CAPABILITY);
4675
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304676 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004677 {
4678 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4679 if(require_ht)
4680 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4681 }
4682}
4683
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304684static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4685 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4686{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004687 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304688 v_U8_t *pIe = NULL;
4689 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4690
4691 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4692 pBeacon->tail, pBeacon->tail_len);
4693
4694 if (pIe)
4695 {
4696 ielen = pIe[1] + 2;
4697 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4698 {
4699 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4700 }
4701 else
4702 {
4703 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4704 return -EINVAL;
4705 }
4706 *total_ielen += ielen;
4707 }
4708 return 0;
4709}
4710
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004711static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4712 v_U8_t *genie, v_U8_t *total_ielen)
4713{
4714 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4715 int left = pBeacon->tail_len;
4716 v_U8_t *ptr = pBeacon->tail;
4717 v_U8_t elem_id, elem_len;
4718 v_U16_t ielen = 0;
4719
4720 if ( NULL == ptr || 0 == left )
4721 return;
4722
4723 while (left >= 2)
4724 {
4725 elem_id = ptr[0];
4726 elem_len = ptr[1];
4727 left -= 2;
4728 if (elem_len > left)
4729 {
4730 hddLog( VOS_TRACE_LEVEL_ERROR,
4731 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4732 elem_id, elem_len, left);
4733 return;
4734 }
4735 if (IE_EID_VENDOR == elem_id)
4736 {
4737 /* skipping the VSIE's which we don't want to include or
4738 * it will be included by existing code
4739 */
4740 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4741#ifdef WLAN_FEATURE_WFD
4742 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4743#endif
4744 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4745 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4746 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4747 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4748 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4749 {
4750 ielen = ptr[1] + 2;
4751 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4752 {
4753 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4754 *total_ielen += ielen;
4755 }
4756 else
4757 {
4758 hddLog( VOS_TRACE_LEVEL_ERROR,
4759 "IE Length is too big "
4760 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4761 elem_id, elem_len, *total_ielen);
4762 }
4763 }
4764 }
4765
4766 left -= elem_len;
4767 ptr += (elem_len + 2);
4768 }
4769 return;
4770}
4771
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004772#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004773static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4774 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004775#else
4776static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4777 struct cfg80211_beacon_data *params)
4778#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004779{
4780 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304781 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004782 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004783 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004784
4785 genie = vos_mem_malloc(MAX_GENIE_LEN);
4786
4787 if(genie == NULL) {
4788
4789 return -ENOMEM;
4790 }
4791
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304792 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4793 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004794 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304795 hddLog(LOGE,
4796 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304797 ret = -EINVAL;
4798 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 }
4800
4801#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304802 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4803 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4804 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304805 hddLog(LOGE,
4806 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304807 ret = -EINVAL;
4808 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004809 }
4810#endif
4811
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304812 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4813 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004814 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304815 hddLog(LOGE,
4816 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304817 ret = -EINVAL;
4818 goto done;
4819 }
4820
4821 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4822 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004823 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004825
4826 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4827 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4828 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4829 {
4830 hddLog(LOGE,
4831 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004832 ret = -EINVAL;
4833 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 }
4835
4836 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4837 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4838 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4839 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4840 ==eHAL_STATUS_FAILURE)
4841 {
4842 hddLog(LOGE,
4843 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004844 ret = -EINVAL;
4845 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004846 }
4847
4848 // Added for ProResp IE
4849 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4850 {
4851 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4852 u8 probe_rsp_ie_len[3] = {0};
4853 u8 counter = 0;
4854 /* Check Probe Resp Length if it is greater then 255 then Store
4855 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4856 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4857 Store More then 255 bytes into One Variable.
4858 */
4859 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4860 {
4861 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4862 {
4863 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4864 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4865 }
4866 else
4867 {
4868 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4869 rem_probe_resp_ie_len = 0;
4870 }
4871 }
4872
4873 rem_probe_resp_ie_len = 0;
4874
4875 if (probe_rsp_ie_len[0] > 0)
4876 {
4877 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4878 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4879 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4880 probe_rsp_ie_len[0], NULL,
4881 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4882 {
4883 hddLog(LOGE,
4884 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004885 ret = -EINVAL;
4886 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004887 }
4888 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4889 }
4890
4891 if (probe_rsp_ie_len[1] > 0)
4892 {
4893 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4894 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4895 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4896 probe_rsp_ie_len[1], NULL,
4897 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4898 {
4899 hddLog(LOGE,
4900 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004901 ret = -EINVAL;
4902 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004903 }
4904 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4905 }
4906
4907 if (probe_rsp_ie_len[2] > 0)
4908 {
4909 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4910 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4911 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4912 probe_rsp_ie_len[2], NULL,
4913 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4914 {
4915 hddLog(LOGE,
4916 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004917 ret = -EINVAL;
4918 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004919 }
4920 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4921 }
4922
4923 if (probe_rsp_ie_len[1] == 0 )
4924 {
4925 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4926 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4927 eANI_BOOLEAN_FALSE) )
4928 {
4929 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004930 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004931 }
4932 }
4933
4934 if (probe_rsp_ie_len[2] == 0 )
4935 {
4936 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4937 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4938 eANI_BOOLEAN_FALSE) )
4939 {
4940 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004941 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004942 }
4943 }
4944
4945 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4946 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4947 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4948 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4949 == eHAL_STATUS_FAILURE)
4950 {
4951 hddLog(LOGE,
4952 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004953 ret = -EINVAL;
4954 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004955 }
4956 }
4957 else
4958 {
4959 // Reset WNI_CFG_PROBE_RSP Flags
4960 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
4961
4962 hddLog(VOS_TRACE_LEVEL_INFO,
4963 "%s: No Probe Response IE received in set beacon",
4964 __func__);
4965 }
4966
4967 // Added for AssocResp IE
4968 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
4969 {
4970 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4971 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
4972 params->assocresp_ies_len, NULL,
4973 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4974 {
4975 hddLog(LOGE,
4976 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004977 ret = -EINVAL;
4978 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004979 }
4980
4981 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4982 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
4983 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4984 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4985 == eHAL_STATUS_FAILURE)
4986 {
4987 hddLog(LOGE,
4988 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004989 ret = -EINVAL;
4990 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 }
4992 }
4993 else
4994 {
4995 hddLog(VOS_TRACE_LEVEL_INFO,
4996 "%s: No Assoc Response IE received in set beacon",
4997 __func__);
4998
4999 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5000 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5001 eANI_BOOLEAN_FALSE) )
5002 {
5003 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005004 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005005 }
5006 }
5007
Jeff Johnsone7245742012-09-05 17:12:55 -07005008done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305010 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005011}
Jeff Johnson295189b2012-06-20 16:38:30 -07005012
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305013/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 * FUNCTION: wlan_hdd_validate_operation_channel
5015 * called by wlan_hdd_cfg80211_start_bss() and
5016 * wlan_hdd_cfg80211_set_channel()
5017 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305018 * channel list.
5019 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005020VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005021{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305022
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 v_U32_t num_ch = 0;
5024 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5025 u32 indx = 0;
5026 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305027 v_U8_t fValidChannel = FALSE, count = 0;
5028 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305029
Jeff Johnson295189b2012-06-20 16:38:30 -07005030 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5031
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305032 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005033 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305034 /* Validate the channel */
5035 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305037 if ( channel == rfChannels[count].channelNum )
5038 {
5039 fValidChannel = TRUE;
5040 break;
5041 }
5042 }
5043 if (fValidChannel != TRUE)
5044 {
5045 hddLog(VOS_TRACE_LEVEL_ERROR,
5046 "%s: Invalid Channel [%d]", __func__, channel);
5047 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005048 }
5049 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305050 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305052 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5053 valid_ch, &num_ch))
5054 {
5055 hddLog(VOS_TRACE_LEVEL_ERROR,
5056 "%s: failed to get valid channel list", __func__);
5057 return VOS_STATUS_E_FAILURE;
5058 }
5059 for (indx = 0; indx < num_ch; indx++)
5060 {
5061 if (channel == valid_ch[indx])
5062 {
5063 break;
5064 }
5065 }
5066
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305067 if (indx >= num_ch)
5068 {
5069 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5070 {
5071 eCsrBand band;
5072 unsigned int freq;
5073
5074 sme_GetFreqBand(hHal, &band);
5075
5076 if (eCSR_BAND_5G == band)
5077 {
5078#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5079 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5080 {
5081 freq = ieee80211_channel_to_frequency(channel,
5082 IEEE80211_BAND_2GHZ);
5083 }
5084 else
5085 {
5086 freq = ieee80211_channel_to_frequency(channel,
5087 IEEE80211_BAND_5GHZ);
5088 }
5089#else
5090 freq = ieee80211_channel_to_frequency(channel);
5091#endif
5092 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5093 return VOS_STATUS_SUCCESS;
5094 }
5095 }
5096
5097 hddLog(VOS_TRACE_LEVEL_ERROR,
5098 "%s: Invalid Channel [%d]", __func__, channel);
5099 return VOS_STATUS_E_FAILURE;
5100 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305102
Jeff Johnson295189b2012-06-20 16:38:30 -07005103 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305104
Jeff Johnson295189b2012-06-20 16:38:30 -07005105}
5106
Viral Modi3a32cc52013-02-08 11:14:52 -08005107/**
5108 * FUNCTION: wlan_hdd_cfg80211_set_channel
5109 * This function is used to set the channel number
5110 */
5111static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5112 struct ieee80211_channel *chan,
5113 enum nl80211_channel_type channel_type
5114 )
5115{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305116 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005117 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005118 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005119 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305120 hdd_context_t *pHddCtx;
5121 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005122
5123 ENTER();
5124
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305125
Viral Modi3a32cc52013-02-08 11:14:52 -08005126 if( NULL == dev )
5127 {
5128 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005129 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005130 return -ENODEV;
5131 }
5132 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305133
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5135 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5136 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005137 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305138 "%s: device_mode = %s (%d) freq = %d", __func__,
5139 hdd_device_modetoString(pAdapter->device_mode),
5140 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305141
5142 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5143 status = wlan_hdd_validate_context(pHddCtx);
5144
5145 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005146 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5148 "%s: HDD context is not valid", __func__);
5149 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005150 }
5151
5152 /*
5153 * Do freq to chan conversion
5154 * TODO: for 11a
5155 */
5156
5157 channel = ieee80211_frequency_to_channel(freq);
5158
5159 /* Check freq range */
5160 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5161 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5162 {
5163 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005164 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005165 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5166 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5167 return -EINVAL;
5168 }
5169
5170 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5171
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305172 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5173 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005174 {
5175 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5176 {
5177 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005178 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005179 return -EINVAL;
5180 }
5181 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5182 "%s: set channel to [%d] for device mode =%d",
5183 __func__, channel,pAdapter->device_mode);
5184 }
5185 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005186 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005187 )
5188 {
5189 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5190 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5191 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5192
5193 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5194 {
5195 /* Link is up then return cant set channel*/
5196 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005197 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005198 return -EINVAL;
5199 }
5200
5201 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5202 pHddStaCtx->conn_info.operationChannel = channel;
5203 pRoamProfile->ChannelInfo.ChannelList =
5204 &pHddStaCtx->conn_info.operationChannel;
5205 }
5206 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005207 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005208 )
5209 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305210 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5211 {
5212 if(VOS_STATUS_SUCCESS !=
5213 wlan_hdd_validate_operation_channel(pAdapter,channel))
5214 {
5215 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005216 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305217 return -EINVAL;
5218 }
5219 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5220 }
5221 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005222 {
5223 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5224
5225 /* If auto channel selection is configured as enable/ 1 then ignore
5226 channel set by supplicant
5227 */
5228 if ( cfg_param->apAutoChannelSelection )
5229 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305230 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5231 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005232 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305233 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5234 __func__, hdd_device_modetoString(pAdapter->device_mode),
5235 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005236 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305237 else
5238 {
5239 if(VOS_STATUS_SUCCESS !=
5240 wlan_hdd_validate_operation_channel(pAdapter,channel))
5241 {
5242 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005243 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305244 return -EINVAL;
5245 }
5246 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5247 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005248 }
5249 }
5250 else
5251 {
5252 hddLog(VOS_TRACE_LEVEL_FATAL,
5253 "%s: Invalid device mode failed to set valid channel", __func__);
5254 return -EINVAL;
5255 }
5256 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305257 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005258}
5259
Jeff Johnson295189b2012-06-20 16:38:30 -07005260#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5261static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5262 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005263#else
5264static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5265 struct cfg80211_beacon_data *params,
5266 const u8 *ssid, size_t ssid_len,
5267 enum nl80211_hidden_ssid hidden_ssid)
5268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005269{
5270 tsap_Config_t *pConfig;
5271 beacon_data_t *pBeacon = NULL;
5272 struct ieee80211_mgmt *pMgmt_frame;
5273 v_U8_t *pIe=NULL;
5274 v_U16_t capab_info;
5275 eCsrAuthType RSNAuthType;
5276 eCsrEncryptionType RSNEncryptType;
5277 eCsrEncryptionType mcRSNEncryptType;
5278 int status = VOS_STATUS_SUCCESS;
5279 tpWLAN_SAPEventCB pSapEventCallback;
5280 hdd_hostapd_state_t *pHostapdState;
5281 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5282 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305283 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005284 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305285 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005287 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005288 v_BOOL_t MFPCapable = VOS_FALSE;
5289 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305290 eHddDot11Mode sapDot11Mode =
5291 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005292
5293 ENTER();
5294
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305295 iniConfig = pHddCtx->cfg_ini;
5296
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5298
5299 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5300
5301 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5302
5303 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5304
5305 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5306
5307 //channel is already set in the set_channel Call back
5308 //pConfig->channel = pCommitConfig->channel;
5309
5310 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305311 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005312 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5313
5314 pConfig->dtim_period = pBeacon->dtim_period;
5315
Arif Hussain6d2a3322013-11-17 19:50:10 -08005316 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005317 pConfig->dtim_period);
5318
5319
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005320 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005321 {
5322 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305324 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5325 {
5326 tANI_BOOLEAN restartNeeded;
5327 pConfig->ieee80211d = 1;
5328 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5329 sme_setRegInfo(hHal, pConfig->countryCode);
5330 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5331 }
5332 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005334 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005335 pConfig->ieee80211d = 1;
5336 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5337 sme_setRegInfo(hHal, pConfig->countryCode);
5338 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005339 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005340 else
5341 {
5342 pConfig->ieee80211d = 0;
5343 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305344 /*
5345 * If auto channel is configured i.e. channel is 0,
5346 * so skip channel validation.
5347 */
5348 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5349 {
5350 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5351 {
5352 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005353 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305354 return -EINVAL;
5355 }
5356 }
5357 else
5358 {
5359 if(1 != pHddCtx->is_dynamic_channel_range_set)
5360 {
5361 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5362 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5363 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5364 }
5365 pHddCtx->is_dynamic_channel_range_set = 0;
5366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005368 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005369 {
5370 pConfig->ieee80211d = 0;
5371 }
5372 pConfig->authType = eSAP_AUTO_SWITCH;
5373
5374 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305375
5376 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005377 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5378
5379 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5380
5381 /*Set wps station to configured*/
5382 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5383
5384 if(pIe)
5385 {
5386 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5387 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005388 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 return -EINVAL;
5390 }
5391 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5392 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005393 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005394 /* Check 15 bit of WPS IE as it contain information for wps state
5395 * WPS state
5396 */
5397 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5398 {
5399 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5400 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5401 {
5402 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5403 }
5404 }
5405 }
5406 else
5407 {
5408 pConfig->wps_state = SAP_WPS_DISABLED;
5409 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305410 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005411
c_hpothufe599e92014-06-16 11:38:55 +05305412 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5413 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5414 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5415 eCSR_ENCRYPT_TYPE_NONE;
5416
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 pConfig->RSNWPAReqIELength = 0;
5418 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305419 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 WLAN_EID_RSN);
5421 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305422 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5424 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5425 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305426 /* The actual processing may eventually be more extensive than
5427 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 * by the app.
5429 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305430 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5432 &RSNEncryptType,
5433 &mcRSNEncryptType,
5434 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005435 &MFPCapable,
5436 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 pConfig->pRSNWPAReqIE[1]+2,
5438 pConfig->pRSNWPAReqIE );
5439
5440 if( VOS_STATUS_SUCCESS == status )
5441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305442 /* Now copy over all the security attributes you have
5443 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 * */
5445 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5446 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5447 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5448 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305449 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005450 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5452 }
5453 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305454
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5456 pBeacon->tail, pBeacon->tail_len);
5457
5458 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5459 {
5460 if (pConfig->pRSNWPAReqIE)
5461 {
5462 /*Mixed mode WPA/WPA2*/
5463 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5464 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5465 }
5466 else
5467 {
5468 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5469 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5470 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305471 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5473 &RSNEncryptType,
5474 &mcRSNEncryptType,
5475 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005476 &MFPCapable,
5477 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 pConfig->pRSNWPAReqIE[1]+2,
5479 pConfig->pRSNWPAReqIE );
5480
5481 if( VOS_STATUS_SUCCESS == status )
5482 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305483 /* Now copy over all the security attributes you have
5484 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 * */
5486 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5487 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5488 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5489 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305490 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005491 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5493 }
5494 }
5495 }
5496
Jeff Johnson4416a782013-03-25 14:17:50 -07005497 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5498 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5499 return -EINVAL;
5500 }
5501
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5503
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005504#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005505 if (params->ssid != NULL)
5506 {
5507 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5508 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5509 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5510 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5511 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005512#else
5513 if (ssid != NULL)
5514 {
5515 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5516 pConfig->SSIDinfo.ssid.length = ssid_len;
5517 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5518 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5519 }
5520#endif
5521
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305522 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305524
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 /* default value */
5526 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5527 pConfig->num_accept_mac = 0;
5528 pConfig->num_deny_mac = 0;
5529
5530 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5531 pBeacon->tail, pBeacon->tail_len);
5532
5533 /* pIe for black list is following form:
5534 type : 1 byte
5535 length : 1 byte
5536 OUI : 4 bytes
5537 acl type : 1 byte
5538 no of mac addr in black list: 1 byte
5539 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305540 */
5541 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 {
5543 pConfig->SapMacaddr_acl = pIe[6];
5544 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005545 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305547 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5548 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5550 for (i = 0; i < pConfig->num_deny_mac; i++)
5551 {
5552 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5553 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 }
5556 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5557 pBeacon->tail, pBeacon->tail_len);
5558
5559 /* pIe for white list is following form:
5560 type : 1 byte
5561 length : 1 byte
5562 OUI : 4 bytes
5563 acl type : 1 byte
5564 no of mac addr in white list: 1 byte
5565 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305566 */
5567 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 {
5569 pConfig->SapMacaddr_acl = pIe[6];
5570 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005571 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305573 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5574 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5576 for (i = 0; i < pConfig->num_accept_mac; i++)
5577 {
5578 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5579 acl_entry++;
5580 }
5581 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305582
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5584
Jeff Johnsone7245742012-09-05 17:12:55 -07005585#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005586 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305587 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5588 * 11ac in .ini and 11ac is supported by both host and firmware.
5589 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5590 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005591 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5592 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305593 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5594 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5595 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5596 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5597 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005598 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305599 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005600 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305601 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005602
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305603 /* If ACS disable and selected channel <= 14
5604 * OR
5605 * ACS enabled and ACS operating band is choosen as 2.4
5606 * AND
5607 * VHT in 2.4G Disabled
5608 * THEN
5609 * Fallback to 11N mode
5610 */
5611 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5612 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305613 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305614 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005615 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305616 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5617 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005618 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5619 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005620 }
5621#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305622
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005623 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5624 {
5625 sme_SelectCBMode(hHal,
5626 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5627 pConfig->channel);
5628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 // ht_capab is not what the name conveys,this is used for protection bitmap
5630 pConfig->ht_capab =
5631 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5632
5633 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5634 {
5635 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5636 return -EINVAL;
5637 }
5638
5639 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305640 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5642 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305643 pConfig->obssProtEnabled =
5644 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005645
Chet Lanctot8cecea22014-02-11 19:09:36 -08005646#ifdef WLAN_FEATURE_11W
5647 pConfig->mfpCapable = MFPCapable;
5648 pConfig->mfpRequired = MFPRequired;
5649 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5650 pConfig->mfpCapable, pConfig->mfpRequired);
5651#endif
5652
Arif Hussain6d2a3322013-11-17 19:50:10 -08005653 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005655 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5656 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5657 (int)pConfig->channel);
5658 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5659 pConfig->SapHw_mode, pConfig->privacy,
5660 pConfig->authType);
5661 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5662 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5663 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5664 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005665
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305666 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005667 {
5668 //Bss already started. just return.
5669 //TODO Probably it should update some beacon params.
5670 hddLog( LOGE, "Bss Already started...Ignore the request");
5671 EXIT();
5672 return 0;
5673 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305674
Jeff Johnson295189b2012-06-20 16:38:30 -07005675 pConfig->persona = pHostapdAdapter->device_mode;
5676
5677 pSapEventCallback = hdd_hostapd_SAPEventCB;
5678 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5679 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5680 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005681 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 return -EINVAL;
5683 }
5684
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305685 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5687
5688 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305689
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305691 {
5692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005693 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005694 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005695 VOS_ASSERT(0);
5696 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305697
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
5699
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005700#ifdef WLAN_FEATURE_P2P_DEBUG
5701 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5702 {
5703 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5704 {
5705 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5706 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005707 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005708 }
5709 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5710 {
5711 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5712 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005713 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005714 }
5715 }
5716#endif
5717
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 pHostapdState->bCommit = TRUE;
5719 EXIT();
5720
5721 return 0;
5722}
5723
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005724#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305725static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5726 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 struct beacon_parameters *params)
5728{
5729 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305730 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305731 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005732
5733 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305734
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5736 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5737 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305738 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5739 hdd_device_modetoString(pAdapter->device_mode),
5740 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005741
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305742 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5743 status = wlan_hdd_validate_context(pHddCtx);
5744
5745 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5748 "%s: HDD context is not valid", __func__);
5749 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005750 }
5751
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305752 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 )
5755 {
5756 beacon_data_t *old,*new;
5757
5758 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305759
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305761 {
5762 hddLog(VOS_TRACE_LEVEL_WARN,
5763 FL("already beacon info added to session(%d)"),
5764 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305766 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005767
5768 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5769
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305770 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 {
5772 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005773 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 return -EINVAL;
5775 }
5776
5777 pAdapter->sessionCtx.ap.beacon = new;
5778
5779 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5780 }
5781
5782 EXIT();
5783 return status;
5784}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305785
5786static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 struct net_device *dev,
5788 struct beacon_parameters *params)
5789{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305791 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5792 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305793 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005794
5795 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5797 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5798 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5800 __func__, hdd_device_modetoString(pAdapter->device_mode),
5801 pAdapter->device_mode);
5802
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305803 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5804 status = wlan_hdd_validate_context(pHddCtx);
5805
5806 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5809 "%s: HDD context is not valid", __func__);
5810 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005811 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305812
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305813 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305815 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 {
5817 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305818
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305820
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305822 {
5823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5824 FL("session(%d) old and new heads points to NULL"),
5825 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305827 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005828
5829 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5830
5831 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305832 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005833 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 return -EINVAL;
5835 }
5836
5837 pAdapter->sessionCtx.ap.beacon = new;
5838
5839 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5840 }
5841
5842 EXIT();
5843 return status;
5844}
5845
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005846#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5847
5848#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005849static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5850 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005851#else
5852static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5853 struct net_device *dev)
5854#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005855{
5856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005857 hdd_context_t *pHddCtx = NULL;
5858 hdd_scaninfo_t *pScanInfo = NULL;
5859 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305860 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305861 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005862
5863 ENTER();
5864
5865 if (NULL == pAdapter)
5866 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005868 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 return -ENODEV;
5870 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005871
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5873 TRACE_CODE_HDD_CFG80211_STOP_AP,
5874 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305875 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5876 status = wlan_hdd_validate_context(pHddCtx);
5877
5878 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005879 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5881 "%s: HDD context is not valid", __func__);
5882 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005883 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005884
5885 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5886 if (NULL == staAdapter)
5887 {
5888 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5889 if (NULL == staAdapter)
5890 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5892 "%s: HDD adapter context for STA/P2P-CLI is Null",
5893 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005894 }
5895 }
5896
5897 pScanInfo = &pHddCtx->scan_info;
5898
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305899 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5900 __func__, hdd_device_modetoString(pAdapter->device_mode),
5901 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305903 ret = wlan_hdd_scan_abort(pAdapter);
5904
Girish Gowli4bf7a632014-06-12 13:42:11 +05305905 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005906 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5908 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305909
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305910 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005911 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5913 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005914
Jeff Johnsone7245742012-09-05 17:12:55 -07005915 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305916 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005917 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305918 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005919 }
5920
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305921 hdd_hostapd_stop(dev);
5922
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 )
5926 {
5927 beacon_data_t *old;
5928
5929 old = pAdapter->sessionCtx.ap.beacon;
5930
5931 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305932 {
5933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5934 FL("session(%d) beacon data points to NULL"),
5935 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305937 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005938
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005940
5941 mutex_lock(&pHddCtx->sap_lock);
5942 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
5943 {
Jeff Johnson4416a782013-03-25 14:17:50 -07005944 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 {
5946 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5947
5948 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
5949
5950 if (!VOS_IS_STATUS_SUCCESS(status))
5951 {
5952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005953 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305955 }
5956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
5958 }
5959 mutex_unlock(&pHddCtx->sap_lock);
5960
5961 if(status != VOS_STATUS_SUCCESS)
5962 {
5963 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005964 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 return -EINVAL;
5966 }
5967
Jeff Johnson4416a782013-03-25 14:17:50 -07005968 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
5970 ==eHAL_STATUS_FAILURE)
5971 {
5972 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005973 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 }
5975
Jeff Johnson4416a782013-03-25 14:17:50 -07005976 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5978 eANI_BOOLEAN_FALSE) )
5979 {
5980 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005981 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 }
5983
5984 // Reset WNI_CFG_PROBE_RSP Flags
5985 wlan_hdd_reset_prob_rspies(pAdapter);
5986
5987 pAdapter->sessionCtx.ap.beacon = NULL;
5988 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005989#ifdef WLAN_FEATURE_P2P_DEBUG
5990 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
5991 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
5992 {
5993 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
5994 "GO got removed");
5995 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
5996 }
5997#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005998 }
5999 EXIT();
6000 return status;
6001}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006002
6003#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6004
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306005static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6006 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006007 struct cfg80211_ap_settings *params)
6008{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306009 hdd_adapter_t *pAdapter;
6010 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306011 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006012
6013 ENTER();
6014
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306015 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006016 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306018 "%s: Device is Null", __func__);
6019 return -ENODEV;
6020 }
6021
6022 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6023 if (NULL == pAdapter)
6024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306026 "%s: HDD adapter is Null", __func__);
6027 return -ENODEV;
6028 }
6029
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306030 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6031 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6032 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306033 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6034 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306036 "%s: HDD adapter magic is invalid", __func__);
6037 return -ENODEV;
6038 }
6039
6040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306041 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306043 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306044 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6046 "%s: HDD context is not valid", __func__);
6047 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306048 }
6049
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306050 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6051 __func__, hdd_device_modetoString(pAdapter->device_mode),
6052 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306053
6054 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006055 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006056 )
6057 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306058 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006059
6060 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306061
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006062 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306063 {
6064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6065 FL("already beacon info added to session(%d)"),
6066 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006067 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306068 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006069
6070 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6071
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306072 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006073 {
6074 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306075 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006076 return -EINVAL;
6077 }
6078 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006080 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6081#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6082 params->channel, params->channel_type);
6083#else
6084 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6085#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006086#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006087 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6088 params->ssid_len, params->hidden_ssid);
6089 }
6090
6091 EXIT();
6092 return status;
6093}
6094
6095
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006097 struct net_device *dev,
6098 struct cfg80211_beacon_data *params)
6099{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306100 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306101 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306102 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006103
6104 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306105
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6107 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6108 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006110 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306111
6112 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6113 status = wlan_hdd_validate_context(pHddCtx);
6114
6115 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006116 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6118 "%s: HDD context is not valid", __func__);
6119 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006120 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006121
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306122 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006123 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006125 {
6126 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306127
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006128 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306129
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006130 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306131 {
6132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6133 FL("session(%d) beacon data points to NULL"),
6134 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006135 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306136 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006137
6138 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6139
6140 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306141 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006142 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006143 return -EINVAL;
6144 }
6145
6146 pAdapter->sessionCtx.ap.beacon = new;
6147
6148 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6149 }
6150
6151 EXIT();
6152 return status;
6153}
6154
6155#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6156
Jeff Johnson295189b2012-06-20 16:38:30 -07006157
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306158static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 struct net_device *dev,
6160 struct bss_parameters *params)
6161{
6162 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6163
6164 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306165
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6167 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6168 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6170 __func__, hdd_device_modetoString(pAdapter->device_mode),
6171 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006172
6173 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306175 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 {
6177 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6178 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306179 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 {
6181 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306182 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 }
6184
6185 EXIT();
6186 return 0;
6187}
6188
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306189static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6190 struct net_device *dev,
6191 struct bss_parameters *params)
6192{
6193 int ret;
6194
6195 vos_ssr_protect(__func__);
6196 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6197 vos_ssr_unprotect(__func__);
6198
6199 return ret;
6200}
Kiet Lam10841362013-11-01 11:36:50 +05306201/* FUNCTION: wlan_hdd_change_country_code_cd
6202* to wait for contry code completion
6203*/
6204void* wlan_hdd_change_country_code_cb(void *pAdapter)
6205{
6206 hdd_adapter_t *call_back_pAdapter = pAdapter;
6207 complete(&call_back_pAdapter->change_country_code);
6208 return NULL;
6209}
6210
Jeff Johnson295189b2012-06-20 16:38:30 -07006211/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306212 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6214 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306215int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 struct net_device *ndev,
6217 enum nl80211_iftype type,
6218 u32 *flags,
6219 struct vif_params *params
6220 )
6221{
6222 struct wireless_dev *wdev;
6223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006224 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006225 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 tCsrRoamProfile *pRoamProfile = NULL;
6227 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306228 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 eMib_dot11DesiredBssType connectedBssType;
6230 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306231 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006232
6233 ENTER();
6234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306235 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006236 {
6237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6238 "%s: Adapter context is null", __func__);
6239 return VOS_STATUS_E_FAILURE;
6240 }
6241
6242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6243 if (!pHddCtx)
6244 {
6245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6246 "%s: HDD context is null", __func__);
6247 return VOS_STATUS_E_FAILURE;
6248 }
6249
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306250 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6251 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6252 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306253 status = wlan_hdd_validate_context(pHddCtx);
6254
6255 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6258 "%s: HDD context is not valid", __func__);
6259 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 }
6261
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6263 __func__, hdd_device_modetoString(pAdapter->device_mode),
6264 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006265
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306266 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 wdev = ndev->ieee80211_ptr;
6268
6269#ifdef WLAN_BTAMP_FEATURE
6270 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6271 (NL80211_IFTYPE_ADHOC == type)||
6272 (NL80211_IFTYPE_AP == type)||
6273 (NL80211_IFTYPE_P2P_GO == type))
6274 {
6275 pHddCtx->isAmpAllowed = VOS_FALSE;
6276 // stop AMP traffic
6277 status = WLANBAP_StopAmp();
6278 if(VOS_STATUS_SUCCESS != status )
6279 {
6280 pHddCtx->isAmpAllowed = VOS_TRUE;
6281 hddLog(VOS_TRACE_LEVEL_FATAL,
6282 "%s: Failed to stop AMP", __func__);
6283 return -EINVAL;
6284 }
6285 }
6286#endif //WLAN_BTAMP_FEATURE
6287 /* Reset the current device mode bit mask*/
6288 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6289
6290 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006292 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 )
6294 {
6295 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006296 if (!pWextState)
6297 {
6298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6299 "%s: pWextState is null", __func__);
6300 return VOS_STATUS_E_FAILURE;
6301 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 pRoamProfile = &pWextState->roamProfile;
6303 LastBSSType = pRoamProfile->BSSType;
6304
6305 switch (type)
6306 {
6307 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 hddLog(VOS_TRACE_LEVEL_INFO,
6310 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6311 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006312#ifdef WLAN_FEATURE_11AC
6313 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6314 {
6315 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6316 }
6317#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006319 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006321 //Check for sub-string p2p to confirm its a p2p interface
6322 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306323 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006324 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6325 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6326 }
6327 else
6328 {
6329 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006331 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306332#ifdef FEATURE_WLAN_TDLS
6333 /* The open adapter for the p2p shall skip initializations in
6334 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6335 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6336 * tdls_init when the change_iface sets the device mode to
6337 * WLAN_HDD_P2P_CLIENT.
6338 */
6339
6340 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6341 {
6342 if (0 != wlan_hdd_tdls_init (pAdapter))
6343 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306344 hddLog(VOS_TRACE_LEVEL_ERROR,
6345 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306346 return -EINVAL;
6347 }
6348 }
6349#endif
6350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 break;
6352 case NL80211_IFTYPE_ADHOC:
6353 hddLog(VOS_TRACE_LEVEL_INFO,
6354 "%s: setting interface Type to ADHOC", __func__);
6355 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6356 pRoamProfile->phyMode =
6357 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006358 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 wdev->iftype = type;
6360 break;
6361
6362 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 {
6365 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6366 "%s: setting interface Type to %s", __func__,
6367 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6368
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006369 //Cancel any remain on channel for GO mode
6370 if (NL80211_IFTYPE_P2P_GO == type)
6371 {
6372 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6373 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006374 if (NL80211_IFTYPE_AP == type)
6375 {
6376 /* As Loading WLAN Driver one interface being created for p2p device
6377 * address. This will take one HW STA and the max number of clients
6378 * that can connect to softAP will be reduced by one. so while changing
6379 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6380 * interface as it is not required in SoftAP mode.
6381 */
6382
6383 // Get P2P Adapter
6384 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6385
6386 if (pP2pAdapter)
6387 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306388 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006389 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6390 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6391 }
6392 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306393 //Disable IMPS & BMPS for SAP/GO
6394 if(VOS_STATUS_E_FAILURE ==
6395 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6396 {
6397 //Fail to Exit BMPS
6398 VOS_ASSERT(0);
6399 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306400#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006401
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306402 /* A Mutex Lock is introduced while changing the mode to
6403 * protect the concurrent access for the Adapters by TDLS
6404 * module.
6405 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306406 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306407#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306409 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006410 hdd_deinit_adapter( pHddCtx, pAdapter );
6411 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6413 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306414#ifdef FEATURE_WLAN_TDLS
6415 mutex_unlock(&pHddCtx->tdls_lock);
6416#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006417 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6418 (pConfig->apRandomBssidEnabled))
6419 {
6420 /* To meet Android requirements create a randomized
6421 MAC address of the form 02:1A:11:Fx:xx:xx */
6422 get_random_bytes(&ndev->dev_addr[3], 3);
6423 ndev->dev_addr[0] = 0x02;
6424 ndev->dev_addr[1] = 0x1A;
6425 ndev->dev_addr[2] = 0x11;
6426 ndev->dev_addr[3] |= 0xF0;
6427 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6428 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006429 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6430 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006431 }
6432
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 hdd_set_ap_ops( pAdapter->dev );
6434
Kiet Lam10841362013-11-01 11:36:50 +05306435 /* This is for only SAP mode where users can
6436 * control country through ini.
6437 * P2P GO follows station country code
6438 * acquired during the STA scanning. */
6439 if((NL80211_IFTYPE_AP == type) &&
6440 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6441 {
6442 int status = 0;
6443 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6444 "%s: setting country code from INI ", __func__);
6445 init_completion(&pAdapter->change_country_code);
6446 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6447 (void *)(tSmeChangeCountryCallback)
6448 wlan_hdd_change_country_code_cb,
6449 pConfig->apCntryCode, pAdapter,
6450 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306451 eSIR_FALSE,
6452 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306453 if (eHAL_STATUS_SUCCESS == status)
6454 {
6455 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306456 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306457 &pAdapter->change_country_code,
6458 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306459 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306460 {
6461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306462 FL("SME Timed out while setting country code %ld"),
6463 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006464
6465 if (pHddCtx->isLogpInProgress)
6466 {
6467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6468 "%s: LOGP in Progress. Ignore!!!", __func__);
6469 return -EAGAIN;
6470 }
Kiet Lam10841362013-11-01 11:36:50 +05306471 }
6472 }
6473 else
6474 {
6475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006476 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306477 return -EINVAL;
6478 }
6479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 status = hdd_init_ap_mode(pAdapter);
6481 if(status != VOS_STATUS_SUCCESS)
6482 {
6483 hddLog(VOS_TRACE_LEVEL_FATAL,
6484 "%s: Error initializing the ap mode", __func__);
6485 return -EINVAL;
6486 }
6487 hdd_set_conparam(1);
6488
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 /*interface type changed update in wiphy structure*/
6490 if(wdev)
6491 {
6492 wdev->iftype = type;
6493 pHddCtx->change_iface = type;
6494 }
6495 else
6496 {
6497 hddLog(VOS_TRACE_LEVEL_ERROR,
6498 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6499 return -EINVAL;
6500 }
6501 goto done;
6502 }
6503
6504 default:
6505 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6506 __func__);
6507 return -EOPNOTSUPP;
6508 }
6509 }
6510 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 )
6513 {
6514 switch(type)
6515 {
6516 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306519#ifdef FEATURE_WLAN_TDLS
6520
6521 /* A Mutex Lock is introduced while changing the mode to
6522 * protect the concurrent access for the Adapters by TDLS
6523 * module.
6524 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306525 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306526#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306527 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006528 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006529 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006530 //Check for sub-string p2p to confirm its a p2p interface
6531 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006532 {
6533 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6534 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6535 }
6536 else
6537 {
6538 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006539 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 hdd_set_conparam(0);
6542 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6544 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306545#ifdef FEATURE_WLAN_TDLS
6546 mutex_unlock(&pHddCtx->tdls_lock);
6547#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306548 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 if( VOS_STATUS_SUCCESS != status )
6550 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006551 /* In case of JB, for P2P-GO, only change interface will be called,
6552 * This is the right place to enable back bmps_imps()
6553 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306554 if (pHddCtx->hdd_wlan_suspended)
6555 {
6556 hdd_set_pwrparams(pHddCtx);
6557 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006558 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 goto done;
6560 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6564 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 goto done;
6566 default:
6567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6568 __func__);
6569 return -EOPNOTSUPP;
6570
6571 }
6572
6573 }
6574 else
6575 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306576 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6577 __func__, hdd_device_modetoString(pAdapter->device_mode),
6578 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 return -EOPNOTSUPP;
6580 }
6581
6582
6583 if(pRoamProfile)
6584 {
6585 if ( LastBSSType != pRoamProfile->BSSType )
6586 {
6587 /*interface type changed update in wiphy structure*/
6588 wdev->iftype = type;
6589
6590 /*the BSS mode changed, We need to issue disconnect
6591 if connected or in IBSS disconnect state*/
6592 if ( hdd_connGetConnectedBssType(
6593 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6594 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6595 {
6596 /*need to issue a disconnect to CSR.*/
6597 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6598 if( eHAL_STATUS_SUCCESS ==
6599 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6600 pAdapter->sessionId,
6601 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6602 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306603 ret = wait_for_completion_interruptible_timeout(
6604 &pAdapter->disconnect_comp_var,
6605 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6606 if (ret <= 0)
6607 {
6608 hddLog(VOS_TRACE_LEVEL_ERROR,
6609 FL("wait on disconnect_comp_var failed %ld"), ret);
6610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 }
6612 }
6613 }
6614 }
6615
6616done:
6617 /*set bitmask based on updated value*/
6618 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006619
6620 /* Only STA mode support TM now
6621 * all other mode, TM feature should be disabled */
6622 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6623 (~VOS_STA & pHddCtx->concurrency_mode) )
6624 {
6625 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6626 }
6627
Jeff Johnson295189b2012-06-20 16:38:30 -07006628#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306629 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
6631 {
6632 //we are ok to do AMP
6633 pHddCtx->isAmpAllowed = VOS_TRUE;
6634 }
6635#endif //WLAN_BTAMP_FEATURE
6636 EXIT();
6637 return 0;
6638}
6639
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306640/*
6641 * FUNCTION: wlan_hdd_cfg80211_change_iface
6642 * wrapper function to protect the actual implementation from SSR.
6643 */
6644int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6645 struct net_device *ndev,
6646 enum nl80211_iftype type,
6647 u32 *flags,
6648 struct vif_params *params
6649 )
6650{
6651 int ret;
6652
6653 vos_ssr_protect(__func__);
6654 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6655 vos_ssr_unprotect(__func__);
6656
6657 return ret;
6658}
6659
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006660#ifdef FEATURE_WLAN_TDLS
6661static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6662 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6663{
6664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6665 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6666 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006667 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306668 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306669 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006670
6671 ENTER();
6672
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306673 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006674 {
6675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6676 "Invalid arguments");
6677 return -EINVAL;
6678 }
Hoonki Lee27511902013-03-14 18:19:06 -07006679
6680 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6681 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6682 {
6683 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6684 "%s: TDLS mode is disabled OR not enabled in FW."
6685 MAC_ADDRESS_STR " Request declined.",
6686 __func__, MAC_ADDR_ARRAY(mac));
6687 return -ENOTSUPP;
6688 }
6689
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006690 if (pHddCtx->isLogpInProgress)
6691 {
6692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6693 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006694 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006695 return -EBUSY;
6696 }
6697
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306698 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006699
6700 if ( NULL == pTdlsPeer ) {
6701 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6702 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6703 __func__, MAC_ADDR_ARRAY(mac), update);
6704 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006705 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006706
6707 /* in add station, we accept existing valid staId if there is */
6708 if ((0 == update) &&
6709 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6710 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006711 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006712 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006713 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006714 " link_status %d. staId %d. add station ignored.",
6715 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6716 return 0;
6717 }
6718 /* in change station, we accept only when staId is valid */
6719 if ((1 == update) &&
6720 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6721 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6722 {
6723 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6724 "%s: " MAC_ADDRESS_STR
6725 " link status %d. staId %d. change station %s.",
6726 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6727 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6728 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006729 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006730
6731 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306732 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006733 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6735 "%s: " MAC_ADDRESS_STR
6736 " TDLS setup is ongoing. Request declined.",
6737 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006738 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006739 }
6740
6741 /* first to check if we reached to maximum supported TDLS peer.
6742 TODO: for now, return -EPERM looks working fine,
6743 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306744 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6745 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006746 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6748 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306749 " TDLS Max peer already connected. Request declined."
6750 " Num of peers (%d), Max allowed (%d).",
6751 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6752 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006753 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006754 }
6755 else
6756 {
6757 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306758 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006759 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006760 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6762 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6763 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006764 return -EPERM;
6765 }
6766 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006767 if (0 == update)
6768 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006769
Jeff Johnsond75fe012013-04-06 10:53:06 -07006770 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306771 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006772 {
6773 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6774 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006775 if(StaParams->htcap_present)
6776 {
6777 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6778 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6779 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6780 "ht_capa->extended_capabilities: %0x",
6781 StaParams->HTCap.extendedHtCapInfo);
6782 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006783 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6784 "params->capability: %0x",StaParams->capability);
6785 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006786 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006787 if(StaParams->vhtcap_present)
6788 {
6789 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6790 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6791 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6792 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6793 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006794 {
6795 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006797 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6798 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6799 "[%d]: %x ", i, StaParams->supported_rates[i]);
6800 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006801 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306802 else if ((1 == update) && (NULL == StaParams))
6803 {
6804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6805 "%s : update is true, but staParams is NULL. Error!", __func__);
6806 return -EPERM;
6807 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006808
6809 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6810
6811 if (!update)
6812 {
6813 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6814 pAdapter->sessionId, mac);
6815 }
6816 else
6817 {
6818 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6819 pAdapter->sessionId, mac, StaParams);
6820 }
6821
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306822 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006823 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6824
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306825 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006826 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306828 "%s: timeout waiting for tdls add station indication %ld",
6829 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006830 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006831 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306832
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006833 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6834 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006836 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006837 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006838 }
6839
6840 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006841
6842error:
6843 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6844 return -EPERM;
6845
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006846}
6847#endif
6848
Jeff Johnson295189b2012-06-20 16:38:30 -07006849static int wlan_hdd_change_station(struct wiphy *wiphy,
6850 struct net_device *dev,
6851 u8 *mac,
6852 struct station_parameters *params)
6853{
6854 VOS_STATUS status = VOS_STATUS_SUCCESS;
6855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306856 hdd_context_t *pHddCtx;
6857 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006859#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006860 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006861 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306862 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006863#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006864 ENTER();
6865
Gopichand Nakkala29149562013-05-10 21:43:41 +05306866 if ((NULL == pAdapter))
6867 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306869 "invalid adapter ");
6870 return -EINVAL;
6871 }
6872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6874 TRACE_CODE_HDD_CHANGE_STATION,
6875 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306876 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6877 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6878
6879 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6880 {
6881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6882 "invalid HDD state or HDD station context");
6883 return -EINVAL;
6884 }
6885
6886 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006887 {
6888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6889 "%s:LOGP in Progress. Ignore!!!", __func__);
6890 return -EAGAIN;
6891 }
6892
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6894
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006895 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6896 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006898 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306900 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 WLANTL_STA_AUTHENTICATED);
6902
Gopichand Nakkala29149562013-05-10 21:43:41 +05306903 if (status != VOS_STATUS_SUCCESS)
6904 {
6905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6906 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6907 return -EINVAL;
6908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 }
6910 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006911 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6912 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306913#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006914 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6915 StaParams.capability = params->capability;
6916 StaParams.uapsd_queues = params->uapsd_queues;
6917 StaParams.max_sp = params->max_sp;
6918
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306919 /* Convert (first channel , number of channels) tuple to
6920 * the total list of channels. This goes with the assumption
6921 * that if the first channel is < 14, then the next channels
6922 * are an incremental of 1 else an incremental of 4 till the number
6923 * of channels.
6924 */
6925 if (0 != params->supported_channels_len) {
6926 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6927 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6928 {
6929 int wifi_chan_index;
6930 StaParams.supported_channels[j] = params->supported_channels[i];
6931 wifi_chan_index =
6932 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6933 no_of_channels = params->supported_channels[i+1];
6934 for(k=1; k <= no_of_channels; k++)
6935 {
6936 StaParams.supported_channels[j+1] =
6937 StaParams.supported_channels[j] + wifi_chan_index;
6938 j+=1;
6939 }
6940 }
6941 StaParams.supported_channels_len = j;
6942 }
6943 vos_mem_copy(StaParams.supported_oper_classes,
6944 params->supported_oper_classes,
6945 params->supported_oper_classes_len);
6946 StaParams.supported_oper_classes_len =
6947 params->supported_oper_classes_len;
6948
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006949 if (0 != params->ext_capab_len)
6950 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
6951 sizeof(StaParams.extn_capability));
6952
6953 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006954 {
6955 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006956 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006957 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006958
6959 StaParams.supported_rates_len = params->supported_rates_len;
6960
6961 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
6962 * The supported_rates array , for all the structures propogating till Add Sta
6963 * to the firmware has to be modified , if the supplicant (ieee80211) is
6964 * modified to send more rates.
6965 */
6966
6967 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
6968 */
6969 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
6970 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
6971
6972 if (0 != StaParams.supported_rates_len) {
6973 int i = 0;
6974 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
6975 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006977 "Supported Rates with Length %d", StaParams.supported_rates_len);
6978 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006980 "[%d]: %0x", i, StaParams.supported_rates[i]);
6981 }
6982
6983 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006984 {
6985 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006986 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006987 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006988
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006989 if (0 != params->ext_capab_len ) {
6990 /*Define A Macro : TODO Sunil*/
6991 if ((1<<4) & StaParams.extn_capability[3]) {
6992 isBufSta = 1;
6993 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306994 /* TDLS Channel Switching Support */
6995 if ((1<<6) & StaParams.extn_capability[3]) {
6996 isOffChannelSupported = 1;
6997 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006998 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306999 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7000 &StaParams, isBufSta,
7001 isOffChannelSupported);
7002
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307003 if (VOS_STATUS_SUCCESS != status) {
7004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7005 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7006 return -EINVAL;
7007 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007008 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7009
7010 if (VOS_STATUS_SUCCESS != status) {
7011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7012 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7013 return -EINVAL;
7014 }
7015 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007016#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307017 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007018 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 return status;
7020}
7021
7022/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307023 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 * This function is used to initialize the key information
7025 */
7026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307027static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 struct net_device *ndev,
7029 u8 key_index, bool pairwise,
7030 const u8 *mac_addr,
7031 struct key_params *params
7032 )
7033#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307034static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 struct net_device *ndev,
7036 u8 key_index, const u8 *mac_addr,
7037 struct key_params *params
7038 )
7039#endif
7040{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 tCsrRoamSetKey setKey;
7043 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307044 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007045 v_U32_t roamId= 0xFF;
7046 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 hdd_hostapd_state_t *pHostapdState;
7048 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007049 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307050 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051
7052 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7055 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7056 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307057 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7058 status = wlan_hdd_validate_context(pHddCtx);
7059
7060 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007061 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7063 "%s: HDD context is not valid", __func__);
7064 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007065 }
7066
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307067 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7068 __func__, hdd_device_modetoString(pAdapter->device_mode),
7069 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007070
7071 if (CSR_MAX_NUM_KEY <= key_index)
7072 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 key_index);
7075
7076 return -EINVAL;
7077 }
7078
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007079 if (CSR_MAX_KEY_LEN < params->key_len)
7080 {
7081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7082 params->key_len);
7083
7084 return -EINVAL;
7085 }
7086
7087 hddLog(VOS_TRACE_LEVEL_INFO,
7088 "%s: called with key index = %d & key length %d",
7089 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007090
7091 /*extract key idx, key len and key*/
7092 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7093 setKey.keyId = key_index;
7094 setKey.keyLength = params->key_len;
7095 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7096
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007097 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 {
7099 case WLAN_CIPHER_SUITE_WEP40:
7100 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7101 break;
7102
7103 case WLAN_CIPHER_SUITE_WEP104:
7104 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7105 break;
7106
7107 case WLAN_CIPHER_SUITE_TKIP:
7108 {
7109 u8 *pKey = &setKey.Key[0];
7110 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7111
7112 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7113
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007114 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007115
7116 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007117 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 |--------------|----------|----------|
7119 <---16bytes---><--8bytes--><--8bytes-->
7120
7121 */
7122 /*Sme expects the 32 bytes key to be in the below order
7123
7124 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007125 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 |--------------|----------|----------|
7127 <---16bytes---><--8bytes--><--8bytes-->
7128 */
7129 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007130 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007131
7132 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007133 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007134
7135 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007136 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007137
7138
7139 break;
7140 }
7141
7142 case WLAN_CIPHER_SUITE_CCMP:
7143 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7144 break;
7145
7146#ifdef FEATURE_WLAN_WAPI
7147 case WLAN_CIPHER_SUITE_SMS4:
7148 {
7149 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7150 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7151 params->key, params->key_len);
7152 return 0;
7153 }
7154#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007155
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007156#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 case WLAN_CIPHER_SUITE_KRK:
7158 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7159 break;
7160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007161
7162#ifdef WLAN_FEATURE_11W
7163 case WLAN_CIPHER_SUITE_AES_CMAC:
7164 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007165 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007166#endif
7167
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007170 __func__, params->cipher);
7171 return -EOPNOTSUPP;
7172 }
7173
7174 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7175 __func__, setKey.encType);
7176
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007177 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007178#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7179 (!pairwise)
7180#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007181 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007182#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007183 )
7184 {
7185 /* set group key*/
7186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7187 "%s- %d: setting Broadcast key",
7188 __func__, __LINE__);
7189 setKey.keyDirection = eSIR_RX_ONLY;
7190 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7191 }
7192 else
7193 {
7194 /* set pairwise key*/
7195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7196 "%s- %d: setting pairwise key",
7197 __func__, __LINE__);
7198 setKey.keyDirection = eSIR_TX_RX;
7199 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7200 }
7201 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7202 {
7203 setKey.keyDirection = eSIR_TX_RX;
7204 /*Set the group key*/
7205 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7206 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007207
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007208 if ( 0 != status )
7209 {
7210 hddLog(VOS_TRACE_LEVEL_ERROR,
7211 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7212 return -EINVAL;
7213 }
7214 /*Save the keys here and call sme_RoamSetKey for setting
7215 the PTK after peer joins the IBSS network*/
7216 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7217 &setKey, sizeof(tCsrRoamSetKey));
7218 return status;
7219 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307220 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7221 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7222 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007224 if( pHostapdState->bssState == BSS_START )
7225 {
c_hpothu7c55da62014-01-23 18:34:02 +05307226 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7227 vos_status = wlan_hdd_check_ula_done(pAdapter);
7228
7229 if ( vos_status != VOS_STATUS_SUCCESS )
7230 {
7231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7232 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7233 __LINE__, vos_status );
7234
7235 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7236
7237 return -EINVAL;
7238 }
7239
Jeff Johnson295189b2012-06-20 16:38:30 -07007240 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7241
7242 if ( status != eHAL_STATUS_SUCCESS )
7243 {
7244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7245 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7246 __LINE__, status );
7247 }
7248 }
7249
7250 /* Saving WEP keys */
7251 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7252 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7253 {
7254 //Save the wep key in ap context. Issue setkey after the BSS is started.
7255 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7256 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7257 }
7258 else
7259 {
7260 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007261 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7263 }
7264 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007265 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7266 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 {
7268 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7269 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7270
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7272 if (!pairwise)
7273#else
7274 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7275#endif
7276 {
7277 /* set group key*/
7278 if (pHddStaCtx->roam_info.deferKeyComplete)
7279 {
7280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7281 "%s- %d: Perform Set key Complete",
7282 __func__, __LINE__);
7283 hdd_PerformRoamSetKeyComplete(pAdapter);
7284 }
7285 }
7286
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7288
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007289 pWextState->roamProfile.Keys.defaultIndex = key_index;
7290
7291
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007292 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 params->key, params->key_len);
7294
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307295
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7297
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307298 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307300 __func__, setKey.peerMac[0], setKey.peerMac[1],
7301 setKey.peerMac[2], setKey.peerMac[3],
7302 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 setKey.keyDirection);
7304
7305 vos_status = wlan_hdd_check_ula_done(pAdapter);
7306
7307 if ( vos_status != VOS_STATUS_SUCCESS )
7308 {
7309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7310 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7311 __LINE__, vos_status );
7312
7313 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7314
7315 return -EINVAL;
7316
7317 }
7318
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007319#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307320 /* The supplicant may attempt to set the PTK once pre-authentication
7321 is done. Save the key in the UMAC and include it in the ADD BSS
7322 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007323 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307324 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007325 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307326 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7327 "%s: Update PreAuth Key success", __func__);
7328 return 0;
7329 }
7330 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7331 {
7332 hddLog(VOS_TRACE_LEVEL_ERROR,
7333 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307334 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007335 }
7336#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007337
7338 /* issue set key request to SME*/
7339 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7340 pAdapter->sessionId, &setKey, &roamId );
7341
7342 if ( 0 != status )
7343 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7346 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7347 return -EINVAL;
7348 }
7349
7350
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307351 /* in case of IBSS as there was no information available about WEP keys during
7352 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307354 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7355 !( ( IW_AUTH_KEY_MGMT_802_1X
7356 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007357 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7358 )
7359 &&
7360 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7361 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7362 )
7363 )
7364 {
7365 setKey.keyDirection = eSIR_RX_ONLY;
7366 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7367
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307368 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307370 __func__, setKey.peerMac[0], setKey.peerMac[1],
7371 setKey.peerMac[2], setKey.peerMac[3],
7372 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 setKey.keyDirection);
7374
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307375 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 pAdapter->sessionId, &setKey, &roamId );
7377
7378 if ( 0 != status )
7379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307380 hddLog(VOS_TRACE_LEVEL_ERROR,
7381 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 __func__, status);
7383 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7384 return -EINVAL;
7385 }
7386 }
7387 }
7388
7389 return 0;
7390}
7391
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7393static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7394 struct net_device *ndev,
7395 u8 key_index, bool pairwise,
7396 const u8 *mac_addr,
7397 struct key_params *params
7398 )
7399#else
7400static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7401 struct net_device *ndev,
7402 u8 key_index, const u8 *mac_addr,
7403 struct key_params *params
7404 )
7405#endif
7406{
7407 int ret;
7408 vos_ssr_protect(__func__);
7409#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7410 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7411 mac_addr, params);
7412#else
7413 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7414 params);
7415#endif
7416 vos_ssr_unprotect(__func__);
7417
7418 return ret;
7419}
7420
Jeff Johnson295189b2012-06-20 16:38:30 -07007421/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307422 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 * This function is used to get the key information
7424 */
7425#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307426static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307427 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007428 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307429 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007430 const u8 *mac_addr, void *cookie,
7431 void (*callback)(void *cookie, struct key_params*)
7432 )
7433#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307434static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307435 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007436 struct net_device *ndev,
7437 u8 key_index, const u8 *mac_addr, void *cookie,
7438 void (*callback)(void *cookie, struct key_params*)
7439 )
7440#endif
7441{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307442 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307443 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7444 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 struct key_params params;
7446
7447 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307448
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7450 __func__, hdd_device_modetoString(pAdapter->device_mode),
7451 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307452
Jeff Johnson295189b2012-06-20 16:38:30 -07007453 memset(&params, 0, sizeof(params));
7454
7455 if (CSR_MAX_NUM_KEY <= key_index)
7456 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007460
7461 switch(pRoamProfile->EncryptionType.encryptionType[0])
7462 {
7463 case eCSR_ENCRYPT_TYPE_NONE:
7464 params.cipher = IW_AUTH_CIPHER_NONE;
7465 break;
7466
7467 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7468 case eCSR_ENCRYPT_TYPE_WEP40:
7469 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7470 break;
7471
7472 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7473 case eCSR_ENCRYPT_TYPE_WEP104:
7474 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7475 break;
7476
7477 case eCSR_ENCRYPT_TYPE_TKIP:
7478 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7479 break;
7480
7481 case eCSR_ENCRYPT_TYPE_AES:
7482 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7483 break;
7484
7485 default:
7486 params.cipher = IW_AUTH_CIPHER_NONE;
7487 break;
7488 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307489
c_hpothuaaf19692014-05-17 17:01:48 +05307490 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7491 TRACE_CODE_HDD_CFG80211_GET_KEY,
7492 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307493
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7495 params.seq_len = 0;
7496 params.seq = NULL;
7497 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7498 callback(cookie, &params);
7499 return 0;
7500}
7501
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307502#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7503static int wlan_hdd_cfg80211_get_key(
7504 struct wiphy *wiphy,
7505 struct net_device *ndev,
7506 u8 key_index, bool pairwise,
7507 const u8 *mac_addr, void *cookie,
7508 void (*callback)(void *cookie, struct key_params*)
7509 )
7510#else
7511static int wlan_hdd_cfg80211_get_key(
7512 struct wiphy *wiphy,
7513 struct net_device *ndev,
7514 u8 key_index, const u8 *mac_addr, void *cookie,
7515 void (*callback)(void *cookie, struct key_params*)
7516 )
7517#endif
7518{
7519 int ret;
7520
7521 vos_ssr_protect(__func__);
7522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7523 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7524 mac_addr, cookie, callback);
7525#else
7526 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7527 callback);
7528#endif
7529 vos_ssr_unprotect(__func__);
7530
7531 return ret;
7532}
7533
Jeff Johnson295189b2012-06-20 16:38:30 -07007534/*
7535 * FUNCTION: wlan_hdd_cfg80211_del_key
7536 * This function is used to delete the key information
7537 */
7538#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307539static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307541 u8 key_index,
7542 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 const u8 *mac_addr
7544 )
7545#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307546static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 struct net_device *ndev,
7548 u8 key_index,
7549 const u8 *mac_addr
7550 )
7551#endif
7552{
7553 int status = 0;
7554
7555 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307556 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 //it is observed that this is invalidating peer
7558 //key index whenever re-key is done. This is affecting data link.
7559 //It should be ok to ignore del_key.
7560#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307561 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7562 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7564 tCsrRoamSetKey setKey;
7565 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307566
Jeff Johnson295189b2012-06-20 16:38:30 -07007567 ENTER();
7568
7569 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7570 __func__,pAdapter->device_mode);
7571
7572 if (CSR_MAX_NUM_KEY <= key_index)
7573 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 key_index);
7576
7577 return -EINVAL;
7578 }
7579
7580 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7581 setKey.keyId = key_index;
7582
7583 if (mac_addr)
7584 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7585 else
7586 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7587
7588 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7589
7590 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007591 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307592 )
7593 {
7594
7595 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7597 if( pHostapdState->bssState == BSS_START)
7598 {
7599 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307600
Jeff Johnson295189b2012-06-20 16:38:30 -07007601 if ( status != eHAL_STATUS_SUCCESS )
7602 {
7603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7604 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7605 __LINE__, status );
7606 }
7607 }
7608 }
7609 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307610 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 )
7612 {
7613 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7614
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307615 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7616
7617 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307619 __func__, setKey.peerMac[0], setKey.peerMac[1],
7620 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307622 if(pAdapter->sessionCtx.station.conn_info.connState ==
7623 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307625 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307627
Jeff Johnson295189b2012-06-20 16:38:30 -07007628 if ( 0 != status )
7629 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307630 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 "%s: sme_RoamSetKey failure, returned %d",
7632 __func__, status);
7633 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7634 return -EINVAL;
7635 }
7636 }
7637 }
7638#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007639 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 return status;
7641}
7642
7643/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307644 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 * This function is used to set the default tx key index
7646 */
7647#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307648static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007649 struct net_device *ndev,
7650 u8 key_index,
7651 bool unicast, bool multicast)
7652#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307653static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007654 struct net_device *ndev,
7655 u8 key_index)
7656#endif
7657{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307659 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307660 hdd_wext_state_t *pWextState;
7661 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307662 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007663
7664 ENTER();
7665
Gopichand Nakkala29149562013-05-10 21:43:41 +05307666 if ((NULL == pAdapter))
7667 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307669 "invalid adapter");
7670 return -EINVAL;
7671 }
7672
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7674 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7675 pAdapter->sessionId, key_index));
7676
Gopichand Nakkala29149562013-05-10 21:43:41 +05307677 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7678 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7679
7680 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7681 {
7682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7683 "invalid Wext state or HDD context");
7684 return -EINVAL;
7685 }
7686
Arif Hussain6d2a3322013-11-17 19:50:10 -08007687 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007688 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307689
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 if (CSR_MAX_NUM_KEY <= key_index)
7691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 key_index);
7694
7695 return -EINVAL;
7696 }
7697
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307698 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7699 status = wlan_hdd_validate_context(pHddCtx);
7700
7701 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007702 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7704 "%s: HDD context is not valid", __func__);
7705 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007706 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307707
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307710 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007711 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307712 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007713 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307714 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007715 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307717 {
7718 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007719 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307720
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 tCsrRoamSetKey setKey;
7722 v_U32_t roamId= 0xFF;
7723 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307724
7725 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307727
Jeff Johnson295189b2012-06-20 16:38:30 -07007728 Keys->defaultIndex = (u8)key_index;
7729 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7730 setKey.keyId = key_index;
7731 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307732
7733 vos_mem_copy(&setKey.Key[0],
7734 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007735 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307736
Gopichand Nakkala29149562013-05-10 21:43:41 +05307737 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307738
7739 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007740 &pHddStaCtx->conn_info.bssId[0],
7741 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307742
Gopichand Nakkala29149562013-05-10 21:43:41 +05307743 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7744 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7745 eCSR_ENCRYPT_TYPE_WEP104)
7746 {
7747 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7748 even though ap is configured for WEP-40 encryption. In this canse the key length
7749 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7750 type(104) and switching encryption type to 40*/
7751 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7752 eCSR_ENCRYPT_TYPE_WEP40;
7753 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7754 eCSR_ENCRYPT_TYPE_WEP40;
7755 }
7756
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307757 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307759
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307761 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307763
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 if ( 0 != status )
7765 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307766 hddLog(VOS_TRACE_LEVEL_ERROR,
7767 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 status);
7769 return -EINVAL;
7770 }
7771 }
7772 }
7773
7774 /* In SoftAp mode setting key direction for default mode */
7775 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7776 {
7777 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7778 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7779 (eCSR_ENCRYPT_TYPE_AES !=
7780 pWextState->roamProfile.EncryptionType.encryptionType[0])
7781 )
7782 {
7783 /* Saving key direction for default key index to TX default */
7784 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7785 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7786 }
7787 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307788
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 return status;
7790}
7791
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307792#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7793static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7794 struct net_device *ndev,
7795 u8 key_index,
7796 bool unicast, bool multicast)
7797#else
7798static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7799 struct net_device *ndev,
7800 u8 key_index)
7801#endif
7802{
7803 int ret;
7804 vos_ssr_protect(__func__);
7805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7806 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7807 multicast);
7808#else
7809 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7810#endif
7811 vos_ssr_unprotect(__func__);
7812
7813 return ret;
7814}
7815
Jeff Johnson295189b2012-06-20 16:38:30 -07007816/*
7817 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7818 * This function is used to inform the BSS details to nl80211 interface.
7819 */
7820static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7821 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7822{
7823 struct net_device *dev = pAdapter->dev;
7824 struct wireless_dev *wdev = dev->ieee80211_ptr;
7825 struct wiphy *wiphy = wdev->wiphy;
7826 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7827 int chan_no;
7828 int ie_length;
7829 const char *ie;
7830 unsigned int freq;
7831 struct ieee80211_channel *chan;
7832 int rssi = 0;
7833 struct cfg80211_bss *bss = NULL;
7834
7835 ENTER();
7836
7837 if( NULL == pBssDesc )
7838 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007839 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 return bss;
7841 }
7842
7843 chan_no = pBssDesc->channelId;
7844 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7845 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7846
7847 if( NULL == ie )
7848 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007849 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 return bss;
7851 }
7852
7853#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7854 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7855 {
7856 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7857 }
7858 else
7859 {
7860 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7861 }
7862#else
7863 freq = ieee80211_channel_to_frequency(chan_no);
7864#endif
7865
7866 chan = __ieee80211_get_channel(wiphy, freq);
7867
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307868 if (!chan) {
7869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7870 return NULL;
7871 }
7872
Abhishek Singhaee43942014-06-16 18:55:47 +05307873 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007874
Abhishek Singhaee43942014-06-16 18:55:47 +05307875 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307876 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 pBssDesc->capabilityInfo,
7878 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307879 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007880}
7881
7882
7883
7884/*
7885 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7886 * This function is used to inform the BSS details to nl80211 interface.
7887 */
7888struct cfg80211_bss*
7889wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7890 tSirBssDescription *bss_desc
7891 )
7892{
7893 /*
7894 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7895 already exists in bss data base of cfg80211 for that particular BSS ID.
7896 Using cfg80211_inform_bss_frame to update the bss entry instead of
7897 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7898 now there is no possibility to get the mgmt(probe response) frame from PE,
7899 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7900 cfg80211_inform_bss_frame.
7901 */
7902 struct net_device *dev = pAdapter->dev;
7903 struct wireless_dev *wdev = dev->ieee80211_ptr;
7904 struct wiphy *wiphy = wdev->wiphy;
7905 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007906#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7907 qcom_ie_age *qie_age = NULL;
7908 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7909#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007911#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 const char *ie =
7913 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7914 unsigned int freq;
7915 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307916 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 struct cfg80211_bss *bss_status = NULL;
7918 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7919 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007920 hdd_context_t *pHddCtx;
7921 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007922#ifdef WLAN_OPEN_SOURCE
7923 struct timespec ts;
7924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007925
Wilson Yangf80a0542013-10-07 13:02:37 -07007926 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7927 status = wlan_hdd_validate_context(pHddCtx);
7928
7929 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307930 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007931 {
7932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7933 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
7934 return NULL;
7935 }
7936
7937
7938 if (0 != status)
7939 {
7940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7941 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007942 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07007943 }
7944
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307945 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07007946 if (!mgmt)
7947 {
7948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7949 "%s: memory allocation failed ", __func__);
7950 return NULL;
7951 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007952
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07007954
7955#ifdef WLAN_OPEN_SOURCE
7956 /* Android does not want the timestamp from the frame.
7957 Instead it wants a monotonic increasing value */
7958 get_monotonic_boottime(&ts);
7959 mgmt->u.probe_resp.timestamp =
7960 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
7961#else
7962 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07007963 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
7964 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07007965
7966#endif
7967
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
7969 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007970
7971#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7972 /* GPS Requirement: need age ie per entry. Using vendor specific. */
7973 /* Assuming this is the last IE, copy at the end */
7974 ie_length -=sizeof(qcom_ie_age);
7975 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
7976 qie_age->element_id = QCOM_VENDOR_IE_ID;
7977 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
7978 qie_age->oui_1 = QCOM_OUI1;
7979 qie_age->oui_2 = QCOM_OUI2;
7980 qie_age->oui_3 = QCOM_OUI3;
7981 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
7982 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
7983#endif
7984
Jeff Johnson295189b2012-06-20 16:38:30 -07007985 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05307986 if (bss_desc->fProbeRsp)
7987 {
7988 mgmt->frame_control |=
7989 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
7990 }
7991 else
7992 {
7993 mgmt->frame_control |=
7994 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
7995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007996
7997#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307998 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8000 {
8001 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8002 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308003 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8005
8006 {
8007 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8008 }
8009 else
8010 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8012 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 kfree(mgmt);
8014 return NULL;
8015 }
8016#else
8017 freq = ieee80211_channel_to_frequency(chan_no);
8018#endif
8019 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008020 /*when the band is changed on the fly using the GUI, three things are done
8021 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
8022 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8023 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8024 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8025 * and discards the channels correponding to previous band and calls back with zero bss results.
8026 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
8027 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8028 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8029 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8030 * So drop the bss and continue to next bss.
8031 */
8032 if(chan == NULL)
8033 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008035 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008036 return NULL;
8037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308039 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 * */
8041 if (( eConnectionState_Associated ==
8042 pAdapter->sessionCtx.station.conn_info.connState ) &&
8043 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8044 pAdapter->sessionCtx.station.conn_info.bssId,
8045 WNI_CFG_BSSID_LEN)))
8046 {
8047 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8048 rssi = (pAdapter->rssi * 100);
8049 }
8050 else
8051 {
8052 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8053 }
8054
Nirav Shah20ac06f2013-12-12 18:14:06 +05308055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8056 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8057 chan->center_freq, (int)(rssi/100));
8058
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8060 frame_len, rssi, GFP_KERNEL);
8061 kfree(mgmt);
8062 return bss_status;
8063}
8064
8065/*
8066 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8067 * This function is used to update the BSS data base of CFG8011
8068 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308069struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008070 tCsrRoamInfo *pRoamInfo
8071 )
8072{
8073 tCsrRoamConnectedProfile roamProfile;
8074 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8075 struct cfg80211_bss *bss = NULL;
8076
8077 ENTER();
8078
8079 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8080 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8081
8082 if (NULL != roamProfile.pBssDesc)
8083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308084 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 &roamProfile);
8086
8087 if (NULL == bss)
8088 {
8089 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8090 __func__);
8091 }
8092
8093 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8094 }
8095 else
8096 {
8097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8098 __func__);
8099 }
8100 return bss;
8101}
8102
8103/*
8104 * FUNCTION: wlan_hdd_cfg80211_update_bss
8105 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308106static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8107 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308109{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308110 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 tCsrScanResultInfo *pScanResult;
8112 eHalStatus status = 0;
8113 tScanResultHandle pResult;
8114 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008115 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008116
8117 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308118
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308119 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8120 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8121 NO_SESSION, pAdapter->sessionId));
8122
Wilson Yangf80a0542013-10-07 13:02:37 -07008123 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8124
8125 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8128 "%s:LOGP in Progress. Ignore!!!",__func__);
8129 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 }
8131
Wilson Yangf80a0542013-10-07 13:02:37 -07008132
8133 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308134 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008135 {
8136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8137 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8138 return VOS_STATUS_E_PERM;
8139 }
8140
8141
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 /*
8143 * start getting scan results and populate cgf80211 BSS database
8144 */
8145 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8146
8147 /* no scan results */
8148 if (NULL == pResult)
8149 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8151 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 return status;
8153 }
8154
8155 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8156
8157 while (pScanResult)
8158 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159 /*
8160 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8161 * entry already exists in bss data base of cfg80211 for that
8162 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8163 * bss entry instead of cfg80211_inform_bss, But this call expects
8164 * mgmt packet as input. As of now there is no possibility to get
8165 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 * ieee80211_mgmt(probe response) and passing to c
8167 * fg80211_inform_bss_frame.
8168 * */
8169
8170 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8171 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308172
Jeff Johnson295189b2012-06-20 16:38:30 -07008173
8174 if (NULL == bss_status)
8175 {
8176 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008177 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 }
8179 else
8180 {
Yue Maf49ba872013-08-19 12:04:25 -07008181 cfg80211_put_bss(
8182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8183 wiphy,
8184#endif
8185 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008186 }
8187
8188 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8189 }
8190
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308191 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008192
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008194}
8195
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008196void
8197hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8198{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308199 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008200 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008201} /****** end hddPrintMacAddr() ******/
8202
8203void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008204hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008205{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308206 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008207 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008208 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8209 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8210 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008211} /****** end hddPrintPmkId() ******/
8212
8213//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8214//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8215
8216//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8217//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8218
8219#define dump_bssid(bssid) \
8220 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008221 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8222 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008223 }
8224
8225#define dump_pmkid(pMac, pmkid) \
8226 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008227 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8228 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008229 }
8230
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008231#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008232/*
8233 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8234 * This function is used to notify the supplicant of a new PMKSA candidate.
8235 */
8236int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308237 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008238 int index, bool preauth )
8239{
Jeff Johnsone7245742012-09-05 17:12:55 -07008240#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008241 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008242 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008243
8244 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008245 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008246
8247 if( NULL == pRoamInfo )
8248 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008249 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008250 return -EINVAL;
8251 }
8252
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008253 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8254 {
8255 dump_bssid(pRoamInfo->bssid);
8256 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008257 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008258 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008259#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308260 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008261}
8262#endif //FEATURE_WLAN_LFR
8263
Yue Maef608272013-04-08 23:09:17 -07008264#ifdef FEATURE_WLAN_LFR_METRICS
8265/*
8266 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8267 * 802.11r/LFR metrics reporting function to report preauth initiation
8268 *
8269 */
8270#define MAX_LFR_METRICS_EVENT_LENGTH 100
8271VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8272 tCsrRoamInfo *pRoamInfo)
8273{
8274 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8275 union iwreq_data wrqu;
8276
8277 ENTER();
8278
8279 if (NULL == pAdapter)
8280 {
8281 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8282 return VOS_STATUS_E_FAILURE;
8283 }
8284
8285 /* create the event */
8286 memset(&wrqu, 0, sizeof(wrqu));
8287 memset(metrics_notification, 0, sizeof(metrics_notification));
8288
8289 wrqu.data.pointer = metrics_notification;
8290 wrqu.data.length = scnprintf(metrics_notification,
8291 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8292 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8293
8294 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8295
8296 EXIT();
8297
8298 return VOS_STATUS_SUCCESS;
8299}
8300
8301/*
8302 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8303 * 802.11r/LFR metrics reporting function to report preauth completion
8304 * or failure
8305 */
8306VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8307 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8308{
8309 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8310 union iwreq_data wrqu;
8311
8312 ENTER();
8313
8314 if (NULL == pAdapter)
8315 {
8316 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8317 return VOS_STATUS_E_FAILURE;
8318 }
8319
8320 /* create the event */
8321 memset(&wrqu, 0, sizeof(wrqu));
8322 memset(metrics_notification, 0, sizeof(metrics_notification));
8323
8324 scnprintf(metrics_notification, sizeof(metrics_notification),
8325 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8326 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8327
8328 if (1 == preauth_status)
8329 strncat(metrics_notification, " TRUE", 5);
8330 else
8331 strncat(metrics_notification, " FALSE", 6);
8332
8333 wrqu.data.pointer = metrics_notification;
8334 wrqu.data.length = strlen(metrics_notification);
8335
8336 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8337
8338 EXIT();
8339
8340 return VOS_STATUS_SUCCESS;
8341}
8342
8343/*
8344 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8345 * 802.11r/LFR metrics reporting function to report handover initiation
8346 *
8347 */
8348VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8349 tCsrRoamInfo *pRoamInfo)
8350{
8351 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8352 union iwreq_data wrqu;
8353
8354 ENTER();
8355
8356 if (NULL == pAdapter)
8357 {
8358 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8359 return VOS_STATUS_E_FAILURE;
8360 }
8361
8362 /* create the event */
8363 memset(&wrqu, 0, sizeof(wrqu));
8364 memset(metrics_notification, 0, sizeof(metrics_notification));
8365
8366 wrqu.data.pointer = metrics_notification;
8367 wrqu.data.length = scnprintf(metrics_notification,
8368 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8369 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8370
8371 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8372
8373 EXIT();
8374
8375 return VOS_STATUS_SUCCESS;
8376}
8377#endif
8378
Jeff Johnson295189b2012-06-20 16:38:30 -07008379/*
8380 * FUNCTION: hdd_cfg80211_scan_done_callback
8381 * scanning callback function, called after finishing scan
8382 *
8383 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308384static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008385 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8386{
8387 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308388 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008390 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8391 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 struct cfg80211_scan_request *req = NULL;
8393 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308394 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308395 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008396
8397 ENTER();
8398
8399 hddLog(VOS_TRACE_LEVEL_INFO,
8400 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008401 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 __func__, halHandle, pContext, (int) scanId, (int) status);
8403
Kiet Lamac06e2c2013-10-23 16:25:07 +05308404 pScanInfo->mScanPendingCounter = 0;
8405
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308407 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 &pScanInfo->scan_req_completion_event,
8409 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308410 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 hddLog(VOS_TRACE_LEVEL_ERROR,
8413 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008415 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 }
8417
Yue Maef608272013-04-08 23:09:17 -07008418 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 {
8420 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008421 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 }
8423
8424 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308425 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 {
8427 hddLog(VOS_TRACE_LEVEL_INFO,
8428 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008429 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 (int) scanId);
8431 }
8432
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308433 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 pAdapter);
8435
8436 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008438
8439
8440 /* If any client wait scan result through WEXT
8441 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008442 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 {
8444 /* The other scan request waiting for current scan finish
8445 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008446 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008448 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 }
8450 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008451 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 {
8453 struct net_device *dev = pAdapter->dev;
8454 union iwreq_data wrqu;
8455 int we_event;
8456 char *msg;
8457
8458 memset(&wrqu, '\0', sizeof(wrqu));
8459 we_event = SIOCGIWSCAN;
8460 msg = NULL;
8461 wireless_send_event(dev, we_event, &wrqu, msg);
8462 }
8463 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008464 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465
8466 /* Get the Scan Req */
8467 req = pAdapter->request;
8468
8469 if (!req)
8470 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008471 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008472 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008473 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 }
8475
8476 /*
8477 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308478 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 req->n_ssids = 0;
8480 req->n_channels = 0;
8481 req->ie = 0;
8482
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008484 /* Scan is no longer pending */
8485 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008486
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008487 /*
8488 * cfg80211_scan_done informing NL80211 about completion
8489 * of scanning
8490 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308491 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8492 {
8493 aborted = true;
8494 }
8495 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008496 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008497
Jeff Johnsone7245742012-09-05 17:12:55 -07008498allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008499 /* release the wake lock at the end of the scan*/
8500 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008501
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008502 /* Acquire wakelock to handle the case where APP's tries to suspend
8503 * immediatly after the driver gets connect request(i.e after scan)
8504 * from supplicant, this result in app's is suspending and not able
8505 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308506 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008507
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008508#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308509 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8510 {
8511 wlan_hdd_tdls_scan_done_callback(pAdapter);
8512 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008513#endif
8514
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 EXIT();
8516 return 0;
8517}
8518
8519/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308520 * FUNCTION: hdd_isConnectionInProgress
8521 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008522 *
8523 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308524v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008525{
8526 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8527 hdd_station_ctx_t *pHddStaCtx = NULL;
8528 hdd_adapter_t *pAdapter = NULL;
8529 VOS_STATUS status = 0;
8530 v_U8_t staId = 0;
8531 v_U8_t *staMac = NULL;
8532
c_hpothu9b781ba2013-12-30 20:57:45 +05308533 if (TRUE == pHddCtx->btCoexModeSet)
8534 {
8535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308536 FL("BTCoex Mode operation in progress"));
8537 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308538 }
8539
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008540 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8541
8542 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8543 {
8544 pAdapter = pAdapterNode->pAdapter;
8545
8546 if( pAdapter )
8547 {
8548 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308549 "%s: Adapter with device mode %s (%d) exists",
8550 __func__, hdd_device_modetoString(pAdapter->device_mode),
8551 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308552 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8553 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8554 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8555 (eConnectionState_Connecting ==
8556 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8557 {
8558 hddLog(VOS_TRACE_LEVEL_ERROR,
8559 "%s: %p(%d) Connection is in progress", __func__,
8560 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8561 return VOS_TRUE;
8562 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008563 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308564 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8565 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008566 {
8567 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8568 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308569 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008570 {
8571 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8572 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008573 "%s: client " MAC_ADDRESS_STR
8574 " is in the middle of WPS/EAPOL exchange.", __func__,
8575 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308576 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008577 }
8578 }
8579 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8580 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8581 {
8582 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308584 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008585 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8586 {
8587 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8588
8589 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008590 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8591 "middle of WPS/EAPOL exchange.", __func__,
8592 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308593 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008594 }
8595 }
8596 }
8597 }
8598 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8599 pAdapterNode = pNext;
8600 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308601 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308602}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008603
8604/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308605 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 * this scan respond to scan trigger and update cfg80211 scan database
8607 * later, scan dump command can be used to recieve scan results
8608 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308609int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008610#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8611 struct net_device *dev,
8612#endif
8613 struct cfg80211_scan_request *request)
8614{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308615 hdd_adapter_t *pAdapter = NULL;
8616 hdd_context_t *pHddCtx = NULL;
8617 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308618 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 tCsrScanRequest scanRequest;
8620 tANI_U8 *channelList = NULL, i;
8621 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308622 int status;
8623 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8627 struct net_device *dev = NULL;
8628 if (NULL == request)
8629 {
8630 hddLog(VOS_TRACE_LEVEL_ERROR,
8631 "%s: scan req param null", __func__);
8632 return -EINVAL;
8633 }
8634 dev = request->wdev->netdev;
8635#endif
8636
8637 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8638 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8639 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8640
Jeff Johnson295189b2012-06-20 16:38:30 -07008641 ENTER();
8642
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308643
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308644 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8645 __func__, hdd_device_modetoString(pAdapter->device_mode),
8646 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308647
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308648 status = wlan_hdd_validate_context(pHddCtx);
8649
8650 if (0 != status)
8651 {
8652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8653 "%s: HDD context is not valid", __func__);
8654 return status;
8655 }
8656
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308657 if (NULL == pwextBuf)
8658 {
8659 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8660 __func__);
8661 return -EIO;
8662 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308663 cfg_param = pHddCtx->cfg_ini;
8664 pScanInfo = &pHddCtx->scan_info;
8665
Jeff Johnson295189b2012-06-20 16:38:30 -07008666#ifdef WLAN_BTAMP_FEATURE
8667 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008668 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008670 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 "%s: No scanning when AMP is on", __func__);
8672 return -EOPNOTSUPP;
8673 }
8674#endif
8675 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008676 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008678 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308679 "%s: Not scanning on device_mode = %s (%d)",
8680 __func__, hdd_device_modetoString(pAdapter->device_mode),
8681 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008682 return -EOPNOTSUPP;
8683 }
8684
8685 if (TRUE == pScanInfo->mScanPending)
8686 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308687 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8688 {
8689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8690 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008691 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 }
8693
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308694 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008695 //Channel and action frame is pending
8696 //Otherwise Cancel Remain On Channel and allow Scan
8697 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008698 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008699 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008701 return -EBUSY;
8702 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008703#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008704 /* if tdls disagree scan right now, return immediately.
8705 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8706 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8707 */
8708 status = wlan_hdd_tdls_scan_callback (pAdapter,
8709 wiphy,
8710#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8711 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008712#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008713 request);
8714 if(status <= 0)
8715 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308716 if(!status)
8717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8718 "scan rejected %d", __func__, status);
8719 else
8720 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8721 __func__, status);
8722
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008723 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008724 }
8725#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008726
Jeff Johnson295189b2012-06-20 16:38:30 -07008727 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8728 {
8729 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008730 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308732 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8734 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308735 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 "%s: MAX TM Level Scan not allowed", __func__);
8737 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308738 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 }
8740 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8741
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008742 /* Check if scan is allowed at this point of time.
8743 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308744 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008745 {
8746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8747 return -EBUSY;
8748 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308749
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8751
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308752 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8753 (int)request->n_ssids);
8754
8755 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8756 * Becasue of this, driver is assuming that this is not wildcard scan and so
8757 * is not aging out the scan results.
8758 */
8759 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308761 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308763
8764 if ((request->ssids) && (0 < request->n_ssids))
8765 {
8766 tCsrSSIDInfo *SsidInfo;
8767 int j;
8768 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8769 /* Allocate num_ssid tCsrSSIDInfo structure */
8770 SsidInfo = scanRequest.SSIDs.SSIDList =
8771 ( tCsrSSIDInfo *)vos_mem_malloc(
8772 request->n_ssids*sizeof(tCsrSSIDInfo));
8773
8774 if(NULL == scanRequest.SSIDs.SSIDList)
8775 {
8776 hddLog(VOS_TRACE_LEVEL_ERROR,
8777 "%s: memory alloc failed SSIDInfo buffer", __func__);
8778 return -ENOMEM;
8779 }
8780
8781 /* copy all the ssid's and their length */
8782 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8783 {
8784 /* get the ssid length */
8785 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8786 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8787 SsidInfo->SSID.length);
8788 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8789 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8790 j, SsidInfo->SSID.ssId);
8791 }
8792 /* set the scan type to active */
8793 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8794 }
8795 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308797 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8798 TRACE_CODE_HDD_CFG80211_SCAN,
8799 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 /* set the scan type to active */
8801 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308803 else
8804 {
8805 /*Set the scan type to default type, in this case it is ACTIVE*/
8806 scanRequest.scanType = pScanInfo->scan_mode;
8807 }
8808 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8809 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008810
8811 /* set BSSType to default type */
8812 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8813
8814 /*TODO: scan the requested channels only*/
8815
8816 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308817 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308819 hddLog(VOS_TRACE_LEVEL_WARN,
8820 "No of Scan Channels exceeded limit: %d", request->n_channels);
8821 request->n_channels = MAX_CHANNEL;
8822 }
8823
8824 hddLog(VOS_TRACE_LEVEL_INFO,
8825 "No of Scan Channels: %d", request->n_channels);
8826
8827
8828 if( request->n_channels )
8829 {
8830 char chList [(request->n_channels*5)+1];
8831 int len;
8832 channelList = vos_mem_malloc( request->n_channels );
8833 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308834 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308835 hddLog(VOS_TRACE_LEVEL_ERROR,
8836 "%s: memory alloc failed channelList", __func__);
8837 status = -ENOMEM;
8838 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308839 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308840
8841 for( i = 0, len = 0; i < request->n_channels ; i++ )
8842 {
8843 channelList[i] = request->channels[i]->hw_value;
8844 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8845 }
8846
Nirav Shah20ac06f2013-12-12 18:14:06 +05308847 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308848 "Channel-List: %s ", chList);
8849 }
c_hpothu53512302014-04-15 18:49:53 +05308850
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308851 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8852 scanRequest.ChannelInfo.ChannelList = channelList;
8853
8854 /* set requestType to full scan */
8855 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8856
8857 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8858 * search (Flush on both full scan and social scan but not on single
8859 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8860 */
8861
8862 /* Supplicant does single channel scan after 8-way handshake
8863 * and in that case driver shoudnt flush scan results. If
8864 * driver flushes the scan results here and unfortunately if
8865 * the AP doesnt respond to our probe req then association
8866 * fails which is not desired
8867 */
8868
8869 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8870 {
8871 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8872 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8873 pAdapter->sessionId );
8874 }
8875
8876 if( request->ie_len )
8877 {
8878 /* save this for future association (join requires this) */
8879 /*TODO: Array needs to be converted to dynamic allocation,
8880 * as multiple ie.s can be sent in cfg80211_scan_request structure
8881 * CR 597966
8882 */
8883 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8884 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8885 pScanInfo->scanAddIE.length = request->ie_len;
8886
8887 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8888 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8889 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308891 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308893 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8894 memcpy( pwextBuf->roamProfile.addIEScan,
8895 request->ie, request->ie_len);
8896 }
8897 else
8898 {
8899 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8900 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 }
8902
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308903 }
8904 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8905 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8906
8907 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8908 request->ie_len);
8909 if (pP2pIe != NULL)
8910 {
8911#ifdef WLAN_FEATURE_P2P_DEBUG
8912 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8913 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8914 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308915 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308916 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8917 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8918 "Go nego completed to Connection is started");
8919 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8920 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308921 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308922 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8923 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308925 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8926 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8927 "Disconnected state to Connection is started");
8928 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8929 "for 4way Handshake");
8930 }
8931#endif
8932
8933 /* no_cck will be set during p2p find to disable 11b rates */
8934 if(TRUE == request->no_cck)
8935 {
8936 hddLog(VOS_TRACE_LEVEL_INFO,
8937 "%s: This is a P2P Search", __func__);
8938 scanRequest.p2pSearch = 1;
8939
8940 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05308941 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308942 /* set requestType to P2P Discovery */
8943 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
8944 }
8945
8946 /*
8947 Skip Dfs Channel in case of P2P Search
8948 if it is set in ini file
8949 */
8950 if(cfg_param->skipDfsChnlInP2pSearch)
8951 {
8952 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308953 }
8954 else
8955 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308956 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008958
Agarwal Ashish4f616132013-12-30 23:32:50 +05308959 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 }
8961 }
8962
8963 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
8964
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008965 /* acquire the wakelock to avoid the apps suspend during the scan. To
8966 * address the following issues.
8967 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
8968 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
8969 * for long time, this result in apps running at full power for long time.
8970 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
8971 * be stuck in full power because of resume BMPS
8972 */
8973 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008974
Nirav Shah20ac06f2013-12-12 18:14:06 +05308975 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8976 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308977 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
8978 scanRequest.requestType, scanRequest.scanType,
8979 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05308980 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
8981
Jeff Johnsone7245742012-09-05 17:12:55 -07008982 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 pAdapter->sessionId, &scanRequest, &scanId,
8984 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07008985
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 if (eHAL_STATUS_SUCCESS != status)
8987 {
8988 hddLog(VOS_TRACE_LEVEL_ERROR,
8989 "%s: sme_ScanRequest returned error %d", __func__, status);
8990 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07008991 if(eHAL_STATUS_RESOURCES == status)
8992 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
8994 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07008995 status = -EBUSY;
8996 } else {
8997 status = -EIO;
8998 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008999 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 goto free_mem;
9001 }
9002
9003 pScanInfo->mScanPending = TRUE;
9004 pAdapter->request = request;
9005 pScanInfo->scanId = scanId;
9006
9007 complete(&pScanInfo->scan_req_completion_event);
9008
9009free_mem:
9010 if( scanRequest.SSIDs.SSIDList )
9011 {
9012 vos_mem_free(scanRequest.SSIDs.SSIDList);
9013 }
9014
9015 if( channelList )
9016 vos_mem_free( channelList );
9017
9018 EXIT();
9019
9020 return status;
9021}
9022
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309023int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9025 struct net_device *dev,
9026#endif
9027 struct cfg80211_scan_request *request)
9028{
9029 int ret;
9030
9031 vos_ssr_protect(__func__);
9032 ret = __wlan_hdd_cfg80211_scan(wiphy,
9033#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9034 dev,
9035#endif
9036 request);
9037 vos_ssr_unprotect(__func__);
9038
9039 return ret;
9040}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009041
9042void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9043{
9044 v_U8_t iniDot11Mode =
9045 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9046 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9047
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309048 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9049 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009050 switch ( iniDot11Mode )
9051 {
9052 case eHDD_DOT11_MODE_AUTO:
9053 case eHDD_DOT11_MODE_11ac:
9054 case eHDD_DOT11_MODE_11ac_ONLY:
9055#ifdef WLAN_FEATURE_11AC
9056 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9057#else
9058 hddDot11Mode = eHDD_DOT11_MODE_11n;
9059#endif
9060 break;
9061 case eHDD_DOT11_MODE_11n:
9062 case eHDD_DOT11_MODE_11n_ONLY:
9063 hddDot11Mode = eHDD_DOT11_MODE_11n;
9064 break;
9065 default:
9066 hddDot11Mode = iniDot11Mode;
9067 break;
9068 }
9069 /* This call decides required channel bonding mode */
9070 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9071 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9072 operationChannel);
9073}
9074
Jeff Johnson295189b2012-06-20 16:38:30 -07009075/*
9076 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309077 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309079int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009080 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009081{
9082 int status = 0;
9083 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009084 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 v_U32_t roamId;
9086 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009087 eCsrAuthType RSNAuthType;
9088
9089 ENTER();
9090
9091 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009092 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9093
9094 status = wlan_hdd_validate_context(pHddCtx);
9095 if (status)
9096 {
9097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9098 "%s: HDD context is not valid!", __func__);
9099 return status;
9100 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309101
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9103 {
9104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9105 return -EINVAL;
9106 }
9107
9108 pRoamProfile = &pWextState->roamProfile;
9109
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309110 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009112 hdd_station_ctx_t *pHddStaCtx;
9113 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009114
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309115 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9117 {
9118 /*QoS not enabled in cfg file*/
9119 pRoamProfile->uapsd_mask = 0;
9120 }
9121 else
9122 {
9123 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309124 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9126 }
9127
9128 pRoamProfile->SSIDs.numOfSSIDs = 1;
9129 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9130 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309131 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009132 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9133 ssid, ssid_len);
9134
9135 if (bssid)
9136 {
9137 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9138 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9139 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309140 /* Save BSSID in seperate variable as well, as RoamProfile
9141 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 case of join failure we should send valid BSSID to supplicant
9143 */
9144 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9145 WNI_CFG_BSSID_LEN);
9146 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009147 else
9148 {
9149 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009151
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309152 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9153 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9155 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309156 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 /*set gen ie*/
9158 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9159 /*set auth*/
9160 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9161 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009162#ifdef FEATURE_WLAN_WAPI
9163 if (pAdapter->wapi_info.nWapiMode)
9164 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009165 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 switch (pAdapter->wapi_info.wapiAuthMode)
9167 {
9168 case WAPI_AUTH_MODE_PSK:
9169 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009170 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 pAdapter->wapi_info.wapiAuthMode);
9172 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9173 break;
9174 }
9175 case WAPI_AUTH_MODE_CERT:
9176 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009177 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 pAdapter->wapi_info.wapiAuthMode);
9179 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9180 break;
9181 }
9182 } // End of switch
9183 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9184 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9185 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009186 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 pRoamProfile->AuthType.numEntries = 1;
9188 pRoamProfile->EncryptionType.numEntries = 1;
9189 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9190 pRoamProfile->mcEncryptionType.numEntries = 1;
9191 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9192 }
9193 }
9194#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309195#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309196 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309197 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9198 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9199 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309200 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9201 sizeof (tSirGtkOffloadParams));
9202 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309203 }
9204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 pRoamProfile->csrPersona = pAdapter->device_mode;
9206
Jeff Johnson32d95a32012-09-10 13:15:23 -07009207 if( operatingChannel )
9208 {
9209 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9210 pRoamProfile->ChannelInfo.numOfChannels = 1;
9211 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009212 else
9213 {
9214 pRoamProfile->ChannelInfo.ChannelList = NULL;
9215 pRoamProfile->ChannelInfo.numOfChannels = 0;
9216 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009217 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9218 {
9219 hdd_select_cbmode(pAdapter,operatingChannel);
9220 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309221
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009222 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9223 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309224 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009225 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009226 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9227 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309228 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9229 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309230 {
9231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9232 "%s: Set HDD connState to eConnectionState_Connecting",
9233 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009234 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9235 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309237 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 pAdapter->sessionId, pRoamProfile, &roamId);
9239
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309240 if ((eHAL_STATUS_SUCCESS != status) &&
9241 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9242 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309243
9244 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9246 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9247 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309248 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009249 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309250 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009251
9252 pRoamProfile->ChannelInfo.ChannelList = NULL;
9253 pRoamProfile->ChannelInfo.numOfChannels = 0;
9254
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 }
9256 else
9257 {
9258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9259 return -EINVAL;
9260 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009261 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009262 return status;
9263}
9264
9265/*
9266 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9267 * This function is used to set the authentication type (OPEN/SHARED).
9268 *
9269 */
9270static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9271 enum nl80211_auth_type auth_type)
9272{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309273 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9275
9276 ENTER();
9277
9278 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309279 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309282 hddLog(VOS_TRACE_LEVEL_INFO,
9283 "%s: set authentication type to AUTOSWITCH", __func__);
9284 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9285 break;
9286
9287 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009288#ifdef WLAN_FEATURE_VOWIFI_11R
9289 case NL80211_AUTHTYPE_FT:
9290#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309291 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 "%s: set authentication type to OPEN", __func__);
9293 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9294 break;
9295
9296 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309297 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 "%s: set authentication type to SHARED", __func__);
9299 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9300 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009301#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 "%s: set authentication type to CCKM WPA", __func__);
9305 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9306 break;
9307#endif
9308
9309
9310 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309311 hddLog(VOS_TRACE_LEVEL_ERROR,
9312 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 auth_type);
9314 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9315 return -EINVAL;
9316 }
9317
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309318 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 pHddStaCtx->conn_info.authType;
9320 return 0;
9321}
9322
9323/*
9324 * FUNCTION: wlan_hdd_set_akm_suite
9325 * This function is used to set the key mgmt type(PSK/8021x).
9326 *
9327 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309328static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 u32 key_mgmt
9330 )
9331{
9332 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9333 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 /*set key mgmt type*/
9336 switch(key_mgmt)
9337 {
9338 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309339#ifdef WLAN_FEATURE_VOWIFI_11R
9340 case WLAN_AKM_SUITE_FT_PSK:
9341#endif
9342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 __func__);
9344 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9345 break;
9346
9347 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309348#ifdef WLAN_FEATURE_VOWIFI_11R
9349 case WLAN_AKM_SUITE_FT_8021X:
9350#endif
9351 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 __func__);
9353 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9354 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009355#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009356#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9357#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9358 case WLAN_AKM_SUITE_CCKM:
9359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9360 __func__);
9361 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9362 break;
9363#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009364#ifndef WLAN_AKM_SUITE_OSEN
9365#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9366 case WLAN_AKM_SUITE_OSEN:
9367 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9368 __func__);
9369 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9370 break;
9371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
9373 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 __func__, key_mgmt);
9376 return -EINVAL;
9377
9378 }
9379 return 0;
9380}
9381
9382/*
9383 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309384 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 * (NONE/WEP40/WEP104/TKIP/CCMP).
9386 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309387static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9388 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 bool ucast
9390 )
9391{
9392 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9395
9396 ENTER();
9397
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309398 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 __func__, cipher);
9402 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9403 }
9404 else
9405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 {
9410 case IW_AUTH_CIPHER_NONE:
9411 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9412 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309413
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309415 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309417
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309419 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309421
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 case WLAN_CIPHER_SUITE_TKIP:
9423 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9424 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309425
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 case WLAN_CIPHER_SUITE_CCMP:
9427 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9428 break;
9429#ifdef FEATURE_WLAN_WAPI
9430 case WLAN_CIPHER_SUITE_SMS4:
9431 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9432 break;
9433#endif
9434
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009435#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 case WLAN_CIPHER_SUITE_KRK:
9437 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9438 break;
9439#endif
9440 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309441 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 __func__, cipher);
9443 return -EOPNOTSUPP;
9444 }
9445 }
9446
9447 if (ucast)
9448 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 __func__, encryptionType);
9451 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9452 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 encryptionType;
9455 }
9456 else
9457 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 __func__, encryptionType);
9460 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9461 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9462 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9463 }
9464
9465 return 0;
9466}
9467
9468
9469/*
9470 * FUNCTION: wlan_hdd_cfg80211_set_ie
9471 * This function is used to parse WPA/RSN IE's.
9472 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309473int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9474 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 size_t ie_len
9476 )
9477{
9478 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9479 u8 *genie = ie;
9480 v_U16_t remLen = ie_len;
9481#ifdef FEATURE_WLAN_WAPI
9482 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9483 u16 *tmp;
9484 v_U16_t akmsuiteCount;
9485 int *akmlist;
9486#endif
9487 ENTER();
9488
9489 /* clear previous assocAddIE */
9490 pWextState->assocAddIE.length = 0;
9491 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009492 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009493
9494 while (remLen >= 2)
9495 {
9496 v_U16_t eLen = 0;
9497 v_U8_t elementId;
9498 elementId = *genie++;
9499 eLen = *genie++;
9500 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309501
Arif Hussain6d2a3322013-11-17 19:50:10 -08009502 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309504
9505 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009508 if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309510 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009511 "%s: Invalid WPA IE", __func__);
9512 return -EINVAL;
9513 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309514 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 {
9516 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309517 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309519
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9521 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009522 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9523 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 VOS_ASSERT(0);
9525 return -ENOMEM;
9526 }
9527 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9528 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9529 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309530
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9532 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9533 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9534 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309535 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9536 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9538 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9539 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9540 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9541 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9542 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309544 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 {
9546 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309549
Jeff Johnson295189b2012-06-20 16:38:30 -07009550 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9551 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009552 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9553 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 VOS_ASSERT(0);
9555 return -ENOMEM;
9556 }
9557 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9558 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9559 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309560
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9562 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009564#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309565 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9566 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 /*Consider WFD IE, only for P2P Client */
9568 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9569 {
9570 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309573
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9575 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009576 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9577 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 VOS_ASSERT(0);
9579 return -ENOMEM;
9580 }
9581 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9582 // WPS IE + P2P IE + WFD IE
9583 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9584 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309585
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9587 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9588 }
9589#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009590 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309591 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009592 HS20_OUI_TYPE_SIZE)) )
9593 {
9594 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309595 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009596 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009597
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009598 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9599 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009600 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9601 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009602 VOS_ASSERT(0);
9603 return -ENOMEM;
9604 }
9605 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9606 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009607
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009608 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9609 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9610 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009611 /* Appending OSEN Information Element in Assiciation Request */
9612 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9613 OSEN_OUI_TYPE_SIZE)) )
9614 {
9615 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9616 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9617 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009618
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009619 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9620 {
9621 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9622 "Need bigger buffer space");
9623 VOS_ASSERT(0);
9624 return -ENOMEM;
9625 }
9626 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9627 pWextState->assocAddIE.length += eLen + 2;
9628
9629 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9630 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9631 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9632 }
9633
9634 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009635 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9636
9637 /* populating as ADDIE in beacon frames */
9638 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9639 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9640 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9641 {
9642 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9643 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9644 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9645 {
9646 hddLog(LOGE,
9647 "Coldn't pass "
9648 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9649 }
9650 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9651 else
9652 hddLog(LOGE,
9653 "Could not pass on "
9654 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9655
9656 /* IBSS mode doesn't contain params->proberesp_ies still
9657 beaconIE's need to be populated in probe response frames */
9658 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9659 {
9660 u16 rem_probe_resp_ie_len = eLen + 2;
9661 u8 probe_rsp_ie_len[3] = {0};
9662 u8 counter = 0;
9663
9664 /* Check Probe Resp Length if it is greater then 255 then
9665 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9666 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9667 not able Store More then 255 bytes into One Variable */
9668
9669 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9670 {
9671 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9672 {
9673 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9674 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9675 }
9676 else
9677 {
9678 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9679 rem_probe_resp_ie_len = 0;
9680 }
9681 }
9682
9683 rem_probe_resp_ie_len = 0;
9684
9685 if (probe_rsp_ie_len[0] > 0)
9686 {
9687 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9688 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9689 (tANI_U8*)(genie - 2),
9690 probe_rsp_ie_len[0], NULL,
9691 eANI_BOOLEAN_FALSE)
9692 == eHAL_STATUS_FAILURE)
9693 {
9694 hddLog(LOGE,
9695 "Could not pass"
9696 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9697 }
9698 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9699 }
9700
9701 if (probe_rsp_ie_len[1] > 0)
9702 {
9703 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9704 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9705 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9706 probe_rsp_ie_len[1], NULL,
9707 eANI_BOOLEAN_FALSE)
9708 == eHAL_STATUS_FAILURE)
9709 {
9710 hddLog(LOGE,
9711 "Could not pass"
9712 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9713 }
9714 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9715 }
9716
9717 if (probe_rsp_ie_len[2] > 0)
9718 {
9719 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9720 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9721 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9722 probe_rsp_ie_len[2], NULL,
9723 eANI_BOOLEAN_FALSE)
9724 == eHAL_STATUS_FAILURE)
9725 {
9726 hddLog(LOGE,
9727 "Could not pass"
9728 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9729 }
9730 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9731 }
9732
9733 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9734 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9735 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9736 {
9737 hddLog(LOGE,
9738 "Could not pass"
9739 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9740 }
9741 }
9742 else
9743 {
9744 // Reset WNI_CFG_PROBE_RSP Flags
9745 wlan_hdd_reset_prob_rspies(pAdapter);
9746
9747 hddLog(VOS_TRACE_LEVEL_INFO,
9748 "%s: No Probe Response IE received in set beacon",
9749 __func__);
9750 }
9751 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 break;
9753 case DOT11F_EID_RSN:
9754 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9755 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9756 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9757 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9758 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9759 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009760 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9761 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309762 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009763 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309764 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009765 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309766
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009767 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9768 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009769 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9770 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009771 VOS_ASSERT(0);
9772 return -ENOMEM;
9773 }
9774 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9775 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309776
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009777 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9778 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9779 break;
9780 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009781#ifdef FEATURE_WLAN_WAPI
9782 case WLAN_EID_WAPI:
9783 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009784 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 pAdapter->wapi_info.nWapiMode);
9786 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309787 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 akmsuiteCount = WPA_GET_LE16(tmp);
9789 tmp = tmp + 1;
9790 akmlist = (int *)(tmp);
9791 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9792 {
9793 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9794 }
9795 else
9796 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009797 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 VOS_ASSERT(0);
9799 return -EINVAL;
9800 }
9801
9802 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9803 {
9804 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009805 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309807 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309809 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009811 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9813 }
9814 break;
9815#endif
9816 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309817 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009819 /* when Unknown IE is received we should break and continue
9820 * to the next IE in the buffer instead we were returning
9821 * so changing this to break */
9822 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 }
9824 genie += eLen;
9825 remLen -= eLen;
9826 }
9827 EXIT();
9828 return 0;
9829}
9830
9831/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309832 * FUNCTION: hdd_isWPAIEPresent
9833 * Parse the received IE to find the WPA IE
9834 *
9835 */
9836static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9837{
9838 v_U8_t eLen = 0;
9839 v_U16_t remLen = ie_len;
9840 v_U8_t elementId = 0;
9841
9842 while (remLen >= 2)
9843 {
9844 elementId = *ie++;
9845 eLen = *ie++;
9846 remLen -= 2;
9847 if (eLen > remLen)
9848 {
9849 hddLog(VOS_TRACE_LEVEL_ERROR,
9850 "%s: IE length is wrong %d", __func__, eLen);
9851 return FALSE;
9852 }
9853 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9854 {
9855 /* OUI - 0x00 0X50 0XF2
9856 WPA Information Element - 0x01
9857 WPA version - 0x01*/
9858 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9859 return TRUE;
9860 }
9861 ie += eLen;
9862 remLen -= eLen;
9863 }
9864 return FALSE;
9865}
9866
9867/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309869 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 * parameters during connect operation.
9871 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309872int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 struct cfg80211_connect_params *req
9874 )
9875{
9876 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309877 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 ENTER();
9879
9880 /*set wpa version*/
9881 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9882
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309883 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309885 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 {
9887 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9888 }
9889 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9890 {
9891 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9892 }
9893 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309894
9895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 pWextState->wpaVersion);
9897
9898 /*set authentication type*/
9899 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9900
9901 if (0 > status)
9902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309903 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 "%s: failed to set authentication type ", __func__);
9905 return status;
9906 }
9907
9908 /*set key mgmt type*/
9909 if (req->crypto.n_akm_suites)
9910 {
9911 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9912 if (0 > status)
9913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 __func__);
9916 return status;
9917 }
9918 }
9919
9920 /*set pairwise cipher type*/
9921 if (req->crypto.n_ciphers_pairwise)
9922 {
9923 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9924 req->crypto.ciphers_pairwise[0], true);
9925 if (0 > status)
9926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309927 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 "%s: failed to set unicast cipher type", __func__);
9929 return status;
9930 }
9931 }
9932 else
9933 {
9934 /*Reset previous cipher suite to none*/
9935 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
9936 if (0 > status)
9937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309938 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 "%s: failed to set unicast cipher type", __func__);
9940 return status;
9941 }
9942 }
9943
9944 /*set group cipher type*/
9945 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
9946 false);
9947
9948 if (0 > status)
9949 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 __func__);
9952 return status;
9953 }
9954
Chet Lanctot186b5732013-03-18 10:26:30 -07009955#ifdef WLAN_FEATURE_11W
9956 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
9957#endif
9958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
9960 if (req->ie_len)
9961 {
9962 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
9963 if ( 0 > status)
9964 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 __func__);
9967 return status;
9968 }
9969 }
9970
9971 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309972 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 {
9974 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
9975 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
9976 )
9977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309978 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
9980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 __func__);
9983 return -EOPNOTSUPP;
9984 }
9985 else
9986 {
9987 u8 key_len = req->key_len;
9988 u8 key_idx = req->key_idx;
9989
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309990 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 && (CSR_MAX_NUM_KEY > key_idx)
9992 )
9993 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309994 hddLog(VOS_TRACE_LEVEL_INFO,
9995 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 __func__, key_idx, key_len);
9997 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309998 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010000 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 (u8)key_len;
10002 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10003 }
10004 }
10005 }
10006 }
10007
10008 return status;
10009}
10010
10011/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010012 * FUNCTION: wlan_hdd_try_disconnect
10013 * This function is used to disconnect from previous
10014 * connection
10015 */
10016static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10017{
10018 long ret = 0;
10019 hdd_station_ctx_t *pHddStaCtx;
10020 eMib_dot11DesiredBssType connectedBssType;
10021
10022 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10023
10024 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10025
10026 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10027 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10028 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10029 {
10030 /* Issue disconnect to CSR */
10031 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10032 if( eHAL_STATUS_SUCCESS ==
10033 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10034 pAdapter->sessionId,
10035 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10036 {
10037 ret = wait_for_completion_interruptible_timeout(
10038 &pAdapter->disconnect_comp_var,
10039 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10040 if (0 >= ret)
10041 {
10042 hddLog(LOGE, FL("Failed to receive disconnect event"));
10043 return -EALREADY;
10044 }
10045 }
10046 }
10047 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10048 {
10049 ret = wait_for_completion_interruptible_timeout(
10050 &pAdapter->disconnect_comp_var,
10051 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10052 if (0 >= ret)
10053 {
10054 hddLog(LOGE, FL("Failed to receive disconnect event"));
10055 return -EALREADY;
10056 }
10057 }
10058
10059 return 0;
10060}
10061
10062/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010063 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 * parameters during connect operation.
10066 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010067static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 struct net_device *ndev,
10069 struct cfg80211_connect_params *req
10070 )
10071{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010072 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010075 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010076
10077 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010078
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10080 TRACE_CODE_HDD_CFG80211_CONNECT,
10081 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010083 "%s: device_mode = %s (%d)", __func__,
10084 hdd_device_modetoString(pAdapter->device_mode),
10085 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010086
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010087 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010088 if (!pHddCtx)
10089 {
10090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10091 "%s: HDD context is null", __func__);
10092 return VOS_STATUS_E_FAILURE;
10093 }
10094
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010095 status = wlan_hdd_validate_context(pHddCtx);
10096
10097 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10100 "%s: HDD context is not valid", __func__);
10101 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 }
10103
10104#ifdef WLAN_BTAMP_FEATURE
10105 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010106 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010108 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010110 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 }
10112#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010113
10114 //If Device Mode is Station Concurrent Sessions Exit BMps
10115 //P2P Mode will be taken care in Open/close adapter
10116 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
10117 (vos_concurrent_sessions_running()))
10118 {
10119 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10120 }
10121
10122 /*Try disconnecting if already in connected state*/
10123 status = wlan_hdd_try_disconnect(pAdapter);
10124 if ( 0 > status)
10125 {
10126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10127 " connection"));
10128 return -EALREADY;
10129 }
10130
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010132 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
10134 if ( 0 > status)
10135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 __func__);
10138 return status;
10139 }
10140
Mohit Khanna765234a2012-09-11 15:08:35 -070010141 if ( req->channel )
10142 {
10143 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10144 req->ssid_len, req->bssid,
10145 req->channel->hw_value);
10146 }
10147 else
10148 {
10149 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010150 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010151 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010152
10153 if (0 > status)
10154 {
10155 //ReEnable BMPS if disabled
10156 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10157 (NULL != pHddCtx))
10158 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010159 if (pHddCtx->hdd_wlan_suspended)
10160 {
10161 hdd_set_pwrparams(pHddCtx);
10162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 //ReEnable Bmps and Imps back
10164 hdd_enable_bmps_imps(pHddCtx);
10165 }
10166
10167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10168 return status;
10169 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010170 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 EXIT();
10172 return status;
10173}
10174
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010175static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10176 struct net_device *ndev,
10177 struct cfg80211_connect_params *req)
10178{
10179 int ret;
10180 vos_ssr_protect(__func__);
10181 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10182 vos_ssr_unprotect(__func__);
10183
10184 return ret;
10185}
Jeff Johnson295189b2012-06-20 16:38:30 -070010186
10187/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010188 * FUNCTION: wlan_hdd_disconnect
10189 * This function is used to issue a disconnect request to SME
10190 */
10191int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10192{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010193 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010194 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010195 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010196 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010197
10198 status = wlan_hdd_validate_context(pHddCtx);
10199
10200 if (0 != status)
10201 {
10202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10203 "%s: HDD context is not valid", __func__);
10204 return status;
10205 }
10206
10207 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10209 "%s: Set HDD connState to eConnectionState_Disconnecting",
10210 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010211 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010212 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010213
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010214 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010215
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010216 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10217 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010218 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10219 {
10220 hddLog(VOS_TRACE_LEVEL_INFO,
10221 FL("status = %d, already disconnected"),
10222 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010223
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010224 }
10225 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010226 {
10227 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010228 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010229 __func__, (int)status );
10230 return -EINVAL;
10231 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010232 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010233 &pAdapter->disconnect_comp_var,
10234 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010235 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010236 {
10237 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010238 "%s: Failed to disconnect, timed out", __func__);
10239 return -ETIMEDOUT;
10240 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010241 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010242 {
10243 hddLog(VOS_TRACE_LEVEL_ERROR,
10244 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010245 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010246 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10248 FL("Set HDD connState to eConnectionState_NotConnected"));
10249 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10250
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010251 /*stop tx queues*/
10252 netif_tx_disable(pAdapter->dev);
10253 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010254 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010255}
10256
10257
10258/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010259 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 * This function is used to issue a disconnect request to SME
10261 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010262static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 struct net_device *dev,
10264 u16 reason
10265 )
10266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010268 tCsrRoamProfile *pRoamProfile =
10269 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010270 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010271 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10272 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010273#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010274 tANI_U8 staIdx;
10275#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010276
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010278
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010279 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10280 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10281 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10283 __func__, hdd_device_modetoString(pAdapter->device_mode),
10284 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010285
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10287 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010288
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010289 status = wlan_hdd_validate_context(pHddCtx);
10290
10291 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10294 "%s: HDD context is not valid", __func__);
10295 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010297
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 if (NULL != pRoamProfile)
10299 {
10300 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010301 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10302 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010306 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 switch(reason)
10308 {
10309 case WLAN_REASON_MIC_FAILURE:
10310 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10311 break;
10312
10313 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10314 case WLAN_REASON_DISASSOC_AP_BUSY:
10315 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10316 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10317 break;
10318
10319 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10320 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010321 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10323 break;
10324
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 default:
10326 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10327 break;
10328 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010329 pScanInfo = &pHddCtx->scan_info;
10330 if (pScanInfo->mScanPending)
10331 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010332 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010333 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010334 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10335 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010337
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010338#ifdef FEATURE_WLAN_TDLS
10339 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010340 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010341 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010342 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10343 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010344 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010345 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010346 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010347 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010348 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010349 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010350 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010351 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010352 pAdapter->sessionId,
10353 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010354 }
10355 }
10356#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010357 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010358 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10359 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 {
10361 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010362 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 __func__, (int)status );
10364 return -EINVAL;
10365 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010367 else
10368 {
10369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10370 "called while in %d state", __func__,
10371 pHddStaCtx->conn_info.connState);
10372 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 }
10374 else
10375 {
10376 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10377 }
10378
10379 return status;
10380}
10381
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010382static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10383 struct net_device *dev,
10384 u16 reason
10385 )
10386{
10387 int ret;
10388 vos_ssr_protect(__func__);
10389 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10390 vos_ssr_unprotect(__func__);
10391
10392 return ret;
10393}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010394
Jeff Johnson295189b2012-06-20 16:38:30 -070010395/*
10396 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010397 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 * settings in IBSS mode.
10399 */
10400static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010401 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 struct cfg80211_ibss_params *params
10403 )
10404{
10405 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010406 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10408 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 ENTER();
10411
10412 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010413 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010414
10415 if (params->ie_len && ( NULL != params->ie) )
10416 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010417 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10418 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010419 {
10420 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10421 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10422 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010423 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010425 tDot11fIEWPA dot11WPAIE;
10426 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010427 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010428
Wilson Yang00256342013-10-10 23:13:38 -070010429 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010430 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10431 params->ie_len, DOT11F_EID_WPA);
10432 if ( NULL != ie )
10433 {
10434 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10435 // Unpack the WPA IE
10436 //Skip past the EID byte and length byte - and four byte WiFi OUI
10437 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10438 &ie[2+4],
10439 ie[1] - 4,
10440 &dot11WPAIE);
10441 /*Extract the multicast cipher, the encType for unicast
10442 cipher for wpa-none is none*/
10443 encryptionType =
10444 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10445 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010447
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10449
10450 if (0 > status)
10451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 __func__);
10454 return status;
10455 }
10456 }
10457
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458 pWextState->roamProfile.AuthType.authType[0] =
10459 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10461
10462 if (params->privacy)
10463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010464 /* Security enabled IBSS, At this time there is no information available
10465 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010467 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010469 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 *enable privacy bit in beacons */
10471
10472 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10473 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010474 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10475 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10477 pWextState->roamProfile.EncryptionType.numEntries = 1;
10478 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 return status;
10480}
10481
10482/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010483 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010486static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 struct net_device *dev,
10488 struct cfg80211_ibss_params *params
10489 )
10490{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10493 tCsrRoamProfile *pRoamProfile;
10494 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010495 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010496 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10497 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010498
10499 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010500
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010501 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10502 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10503 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010504 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010505 "%s: device_mode = %s (%d)", __func__,
10506 hdd_device_modetoString(pAdapter->device_mode),
10507 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010509 status = wlan_hdd_validate_context(pHddCtx);
10510
10511 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10514 "%s: HDD context is not valid", __func__);
10515 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 }
10517
10518 if (NULL == pWextState)
10519 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010520 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 __func__);
10522 return -EIO;
10523 }
10524
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010525 /*Try disconnecting if already in connected state*/
10526 status = wlan_hdd_try_disconnect(pAdapter);
10527 if ( 0 > status)
10528 {
10529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10530 " IBSS connection"));
10531 return -EALREADY;
10532 }
10533
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 pRoamProfile = &pWextState->roamProfile;
10535
10536 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10537 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010538 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010539 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010540 return -EINVAL;
10541 }
10542
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010543 /* BSSID is provided by upper layers hence no need to AUTO generate */
10544 if (NULL != params->bssid) {
10545 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10546 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10547 hddLog (VOS_TRACE_LEVEL_ERROR,
10548 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10549 return -EIO;
10550 }
10551 }
krunal sonie9002db2013-11-25 14:24:17 -080010552 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10553 {
10554 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10555 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10556 {
10557 hddLog (VOS_TRACE_LEVEL_ERROR,
10558 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10559 return -EIO;
10560 }
10561 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10562 if (!params->bssid)
10563 {
10564 hddLog (VOS_TRACE_LEVEL_ERROR,
10565 "%s:Failed memory allocation", __func__);
10566 return -EIO;
10567 }
10568 vos_mem_copy((v_U8_t *)params->bssid,
10569 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10570 VOS_MAC_ADDR_SIZE);
10571 alloc_bssid = VOS_TRUE;
10572 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010573
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010575 if (NULL !=
10576#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10577 params->chandef.chan)
10578#else
10579 params->channel)
10580#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 {
10582 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010583 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10584 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10585 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10586 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010587
10588 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010590 ieee80211_frequency_to_channel(
10591#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10592 params->chandef.chan->center_freq);
10593#else
10594 params->channel->center_freq);
10595#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010596
10597 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10598 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10601 __func__);
10602 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010604
10605 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010607 if (channelNum == validChan[indx])
10608 {
10609 break;
10610 }
10611 }
10612 if (indx >= numChans)
10613 {
10614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010615 __func__, channelNum);
10616 return -EINVAL;
10617 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010618 /* Set the Operational Channel */
10619 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10620 channelNum);
10621 pRoamProfile->ChannelInfo.numOfChannels = 1;
10622 pHddStaCtx->conn_info.operationChannel = channelNum;
10623 pRoamProfile->ChannelInfo.ChannelList =
10624 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010625 }
10626
10627 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010628 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 if (status < 0)
10630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010632 __func__);
10633 return status;
10634 }
10635
10636 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010637 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010638 params->ssid_len, params->bssid,
10639 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010640
10641 if (0 > status)
10642 {
10643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10644 return status;
10645 }
10646
krunal sonie9002db2013-11-25 14:24:17 -080010647 if (NULL != params->bssid &&
10648 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10649 alloc_bssid == VOS_TRUE)
10650 {
10651 vos_mem_free(params->bssid);
10652 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010653 return 0;
10654}
10655
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010656static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10657 struct net_device *dev,
10658 struct cfg80211_ibss_params *params
10659 )
10660{
10661 int ret = 0;
10662
10663 vos_ssr_protect(__func__);
10664 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10665 vos_ssr_unprotect(__func__);
10666
10667 return ret;
10668}
10669
Jeff Johnson295189b2012-06-20 16:38:30 -070010670/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010671 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010672 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010674static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 struct net_device *dev
10676 )
10677{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010679 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10680 tCsrRoamProfile *pRoamProfile;
10681 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010682 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010683
10684 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010685
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10687 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10688 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010689 status = wlan_hdd_validate_context(pHddCtx);
10690
10691 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010692 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10694 "%s: HDD context is not valid", __func__);
10695 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010696 }
10697
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010698 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10699 hdd_device_modetoString(pAdapter->device_mode),
10700 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 if (NULL == pWextState)
10702 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010703 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 __func__);
10705 return -EIO;
10706 }
10707
10708 pRoamProfile = &pWextState->roamProfile;
10709
10710 /* Issue disconnect only if interface type is set to IBSS */
10711 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010713 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010714 __func__);
10715 return -EINVAL;
10716 }
10717
10718 /* Issue Disconnect request */
10719 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10720 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10721 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10722
10723 return 0;
10724}
10725
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010726static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10727 struct net_device *dev
10728 )
10729{
10730 int ret = 0;
10731
10732 vos_ssr_protect(__func__);
10733 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10734 vos_ssr_unprotect(__func__);
10735
10736 return ret;
10737}
10738
Jeff Johnson295189b2012-06-20 16:38:30 -070010739/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010740 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 * This function is used to set the phy parameters
10742 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10743 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010744static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 u32 changed)
10746{
10747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10748 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010749 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010750
10751 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010752 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10753 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10754 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010755 status = wlan_hdd_validate_context(pHddCtx);
10756
10757 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010758 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10760 "%s: HDD context is not valid", __func__);
10761 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010762 }
10763
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10765 {
10766 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10767 WNI_CFG_RTS_THRESHOLD_STAMAX :
10768 wiphy->rts_threshold;
10769
10770 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010771 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010773 hddLog(VOS_TRACE_LEVEL_ERROR,
10774 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 __func__, rts_threshold);
10776 return -EINVAL;
10777 }
10778
10779 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10780 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010781 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010783 hddLog(VOS_TRACE_LEVEL_ERROR,
10784 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010785 __func__, rts_threshold);
10786 return -EIO;
10787 }
10788
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 rts_threshold);
10791 }
10792
10793 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10794 {
10795 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10796 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10797 wiphy->frag_threshold;
10798
10799 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010800 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010801 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010802 hddLog(VOS_TRACE_LEVEL_ERROR,
10803 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 frag_threshold);
10805 return -EINVAL;
10806 }
10807
10808 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10809 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010810 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010812 hddLog(VOS_TRACE_LEVEL_ERROR,
10813 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010814 __func__, frag_threshold);
10815 return -EIO;
10816 }
10817
10818 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10819 frag_threshold);
10820 }
10821
10822 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10823 || (changed & WIPHY_PARAM_RETRY_LONG))
10824 {
10825 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10826 wiphy->retry_short :
10827 wiphy->retry_long;
10828
10829 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10830 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 __func__, retry_value);
10834 return -EINVAL;
10835 }
10836
10837 if (changed & WIPHY_PARAM_RETRY_SHORT)
10838 {
10839 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10840 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010841 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010843 hddLog(VOS_TRACE_LEVEL_ERROR,
10844 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 __func__, retry_value);
10846 return -EIO;
10847 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010848 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 __func__, retry_value);
10850 }
10851 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10852 {
10853 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10854 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010857 hddLog(VOS_TRACE_LEVEL_ERROR,
10858 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 __func__, retry_value);
10860 return -EIO;
10861 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 __func__, retry_value);
10864 }
10865 }
10866
10867 return 0;
10868}
10869
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010870static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10871 u32 changed)
10872{
10873 int ret;
10874
10875 vos_ssr_protect(__func__);
10876 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10877 vos_ssr_unprotect(__func__);
10878
10879 return ret;
10880}
10881
Jeff Johnson295189b2012-06-20 16:38:30 -070010882/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010883 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 * This function is used to set the txpower
10885 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010886static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010887#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10888 struct wireless_dev *wdev,
10889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010890#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010891 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010892#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010893 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010894#endif
10895 int dbm)
10896{
10897 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010898 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10900 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010901 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010902
10903 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010904 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10905 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10906 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010907 status = wlan_hdd_validate_context(pHddCtx);
10908
10909 if (0 != status)
10910 {
10911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10912 "%s: HDD context is not valid", __func__);
10913 return status;
10914 }
10915
10916 hHal = pHddCtx->hHal;
10917
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010918 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10919 dbm, ccmCfgSetCallback,
10920 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010922 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10924 return -EIO;
10925 }
10926
10927 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
10928 dbm);
10929
10930 switch(type)
10931 {
10932 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
10933 /* Fall through */
10934 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
10935 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
10936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
10938 __func__);
10939 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 }
10941 break;
10942 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010944 __func__);
10945 return -EOPNOTSUPP;
10946 break;
10947 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
10949 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 return -EIO;
10951 }
10952
10953 return 0;
10954}
10955
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010956static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
10957#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10958 struct wireless_dev *wdev,
10959#endif
10960#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
10961 enum tx_power_setting type,
10962#else
10963 enum nl80211_tx_power_setting type,
10964#endif
10965 int dbm)
10966{
10967 int ret;
10968 vos_ssr_protect(__func__);
10969 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
10970#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10971 wdev,
10972#endif
10973#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
10974 type,
10975#else
10976 type,
10977#endif
10978 dbm);
10979 vos_ssr_unprotect(__func__);
10980
10981 return ret;
10982}
10983
Jeff Johnson295189b2012-06-20 16:38:30 -070010984/*
10985 * FUNCTION: wlan_hdd_cfg80211_get_txpower
10986 * This function is used to read the txpower
10987 */
Yue Maf49ba872013-08-19 12:04:25 -070010988static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
10989#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10990 struct wireless_dev *wdev,
10991#endif
10992 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070010993{
10994
10995 hdd_adapter_t *pAdapter;
10996 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010997 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010998
Jeff Johnsone7245742012-09-05 17:12:55 -070010999 ENTER();
11000
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011001 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011002
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011003 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011004 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11006 "%s: HDD context is not valid", __func__);
11007 *dbm = 0;
11008 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011009 }
11010
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11012 if (NULL == pAdapter)
11013 {
11014 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11015 return -ENOENT;
11016 }
11017
11018 wlan_hdd_get_classAstats(pAdapter);
11019 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11020
Jeff Johnsone7245742012-09-05 17:12:55 -070011021 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 return 0;
11023}
11024
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011025static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 u8* mac, struct station_info *sinfo)
11027{
11028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11029 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11030 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011031 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011032
11033 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11034 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011035
11036 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11037 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11038 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11039 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11040 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11041 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11042 tANI_U16 maxRate = 0;
11043 tANI_U16 myRate;
11044 tANI_U16 currentRate = 0;
11045 tANI_U8 maxSpeedMCS = 0;
11046 tANI_U8 maxMCSIdx = 0;
11047 tANI_U8 rateFlag = 1;
11048 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011049 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011050 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011051
Leo Chang6f8870f2013-03-26 18:11:36 -070011052#ifdef WLAN_FEATURE_11AC
11053 tANI_U32 vht_mcs_map;
11054 eDataRate11ACMaxMcs vhtMaxMcs;
11055#endif /* WLAN_FEATURE_11AC */
11056
Jeff Johnsone7245742012-09-05 17:12:55 -070011057 ENTER();
11058
Jeff Johnson295189b2012-06-20 16:38:30 -070011059 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11060 (0 == ssidlen))
11061 {
11062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11063 " Invalid ssidlen, %d", __func__, ssidlen);
11064 /*To keep GUI happy*/
11065 return 0;
11066 }
11067
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011068 status = wlan_hdd_validate_context(pHddCtx);
11069
11070 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11073 "%s: HDD context is not valid", __func__);
11074 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011075 }
11076
Jeff Johnson295189b2012-06-20 16:38:30 -070011077
Kiet Lam3b17fc82013-09-27 05:24:08 +053011078 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11079 sinfo->filled |= STATION_INFO_SIGNAL;
11080
c_hpothu09f19542014-05-30 21:53:31 +053011081 wlan_hdd_get_station_stats(pAdapter);
11082 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11083
11084 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011085 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11086 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11087 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11088 {
11089 rate_flags = pAdapter->maxRateFlags;
11090 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011091
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 //convert to the UI units of 100kbps
11093 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11094
11095#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011096 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 sinfo->signal,
11098 pCfg->reportMaxLinkSpeed,
11099 myRate,
11100 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011101 (int) pCfg->linkSpeedRssiMid,
11102 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011103 (int) rate_flags,
11104 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011105#endif //LINKSPEED_DEBUG_ENABLED
11106
11107 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11108 {
11109 // we do not want to necessarily report the current speed
11110 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11111 {
11112 // report the max possible speed
11113 rssidx = 0;
11114 }
11115 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11116 {
11117 // report the max possible speed with RSSI scaling
11118 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11119 {
11120 // report the max possible speed
11121 rssidx = 0;
11122 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011123 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011124 {
11125 // report middle speed
11126 rssidx = 1;
11127 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011128 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11129 {
11130 // report middle speed
11131 rssidx = 2;
11132 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 else
11134 {
11135 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011136 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 }
11138 }
11139 else
11140 {
11141 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11142 hddLog(VOS_TRACE_LEVEL_ERROR,
11143 "%s: Invalid value for reportMaxLinkSpeed: %u",
11144 __func__, pCfg->reportMaxLinkSpeed);
11145 rssidx = 0;
11146 }
11147
11148 maxRate = 0;
11149
11150 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011151 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11152 OperationalRates, &ORLeng))
11153 {
11154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11155 /*To keep GUI happy*/
11156 return 0;
11157 }
11158
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 for (i = 0; i < ORLeng; i++)
11160 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011161 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 {
11163 /* Validate Rate Set */
11164 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11165 {
11166 currentRate = supported_data_rate[j].supported_rate[rssidx];
11167 break;
11168 }
11169 }
11170 /* Update MAX rate */
11171 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11172 }
11173
11174 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011175 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11176 ExtendedRates, &ERLeng))
11177 {
11178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11179 /*To keep GUI happy*/
11180 return 0;
11181 }
11182
Jeff Johnson295189b2012-06-20 16:38:30 -070011183 for (i = 0; i < ERLeng; i++)
11184 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011185 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 {
11187 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11188 {
11189 currentRate = supported_data_rate[j].supported_rate[rssidx];
11190 break;
11191 }
11192 }
11193 /* Update MAX rate */
11194 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11195 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011196 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011197 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011198 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011199 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011200 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011202 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11203 MCSRates, &MCSLeng))
11204 {
11205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11206 /*To keep GUI happy*/
11207 return 0;
11208 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011210#ifdef WLAN_FEATURE_11AC
11211 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011212 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011214 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011215 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011216 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011218 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011220 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011221 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011222 maxMCSIdx = 7;
11223 }
11224 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11225 {
11226 maxMCSIdx = 8;
11227 }
11228 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11229 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011230 //VHT20 is supporting 0~8
11231 if (rate_flags & eHAL_TX_RATE_VHT20)
11232 maxMCSIdx = 8;
11233 else
11234 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011235 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011236
11237 if (rate_flags & eHAL_TX_RATE_VHT80)
11238 {
11239 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11240 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11241 }
11242 else if (rate_flags & eHAL_TX_RATE_VHT40)
11243 {
11244 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11245 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11246 }
11247 else if (rate_flags & eHAL_TX_RATE_VHT20)
11248 {
11249 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11250 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11251 }
11252
Leo Chang6f8870f2013-03-26 18:11:36 -070011253 maxSpeedMCS = 1;
11254 if (currentRate > maxRate)
11255 {
11256 maxRate = currentRate;
11257 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011258
Leo Chang6f8870f2013-03-26 18:11:36 -070011259 }
11260 else
11261#endif /* WLAN_FEATURE_11AC */
11262 {
11263 if (rate_flags & eHAL_TX_RATE_HT40)
11264 {
11265 rateFlag |= 1;
11266 }
11267 if (rate_flags & eHAL_TX_RATE_SGI)
11268 {
11269 rateFlag |= 2;
11270 }
11271
11272 for (i = 0; i < MCSLeng; i++)
11273 {
11274 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11275 for (j = 0; j < temp; j++)
11276 {
11277 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11278 {
11279 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11280 break;
11281 }
11282 }
11283 if ((j < temp) && (currentRate > maxRate))
11284 {
11285 maxRate = currentRate;
11286 maxSpeedMCS = 1;
11287 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11288 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 }
11290 }
11291 }
11292
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011293 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11294 {
11295 maxRate = myRate;
11296 maxSpeedMCS = 1;
11297 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11298 }
11299
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011301 if (((maxRate < myRate) && (0 == rssidx)) ||
11302 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 {
11304 maxRate = myRate;
11305 if (rate_flags & eHAL_TX_RATE_LEGACY)
11306 {
11307 maxSpeedMCS = 0;
11308 }
11309 else
11310 {
11311 maxSpeedMCS = 1;
11312 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11313 }
11314 }
11315
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011316 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 {
11318 sinfo->txrate.legacy = maxRate;
11319#ifdef LINKSPEED_DEBUG_ENABLED
11320 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11321#endif //LINKSPEED_DEBUG_ENABLED
11322 }
11323 else
11324 {
11325 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011326#ifdef WLAN_FEATURE_11AC
11327 sinfo->txrate.nss = 1;
11328 if (rate_flags & eHAL_TX_RATE_VHT80)
11329 {
11330 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011331 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011332 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011333 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011334 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011335 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11336 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11337 }
11338 else if (rate_flags & eHAL_TX_RATE_VHT20)
11339 {
11340 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11341 }
11342#endif /* WLAN_FEATURE_11AC */
11343 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11344 {
11345 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11346 if (rate_flags & eHAL_TX_RATE_HT40)
11347 {
11348 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11349 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011350 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 if (rate_flags & eHAL_TX_RATE_SGI)
11352 {
11353 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11354 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011355
Jeff Johnson295189b2012-06-20 16:38:30 -070011356#ifdef LINKSPEED_DEBUG_ENABLED
11357 pr_info("Reporting MCS rate %d flags %x\n",
11358 sinfo->txrate.mcs,
11359 sinfo->txrate.flags );
11360#endif //LINKSPEED_DEBUG_ENABLED
11361 }
11362 }
11363 else
11364 {
11365 // report current rate instead of max rate
11366
11367 if (rate_flags & eHAL_TX_RATE_LEGACY)
11368 {
11369 //provide to the UI in units of 100kbps
11370 sinfo->txrate.legacy = myRate;
11371#ifdef LINKSPEED_DEBUG_ENABLED
11372 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11373#endif //LINKSPEED_DEBUG_ENABLED
11374 }
11375 else
11376 {
11377 //must be MCS
11378 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011379#ifdef WLAN_FEATURE_11AC
11380 sinfo->txrate.nss = 1;
11381 if (rate_flags & eHAL_TX_RATE_VHT80)
11382 {
11383 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11384 }
11385 else
11386#endif /* WLAN_FEATURE_11AC */
11387 {
11388 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 if (rate_flags & eHAL_TX_RATE_SGI)
11391 {
11392 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11393 }
11394 if (rate_flags & eHAL_TX_RATE_HT40)
11395 {
11396 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11397 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011398#ifdef WLAN_FEATURE_11AC
11399 else if (rate_flags & eHAL_TX_RATE_VHT80)
11400 {
11401 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11402 }
11403#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011404#ifdef LINKSPEED_DEBUG_ENABLED
11405 pr_info("Reporting actual MCS rate %d flags %x\n",
11406 sinfo->txrate.mcs,
11407 sinfo->txrate.flags );
11408#endif //LINKSPEED_DEBUG_ENABLED
11409 }
11410 }
11411 sinfo->filled |= STATION_INFO_TX_BITRATE;
11412
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011413 sinfo->tx_packets =
11414 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11415 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11416 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11417 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11418
11419 sinfo->tx_retries =
11420 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11421 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11422 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11423 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11424
11425 sinfo->tx_failed =
11426 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11427 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11428 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11429 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11430
11431 sinfo->filled |=
11432 STATION_INFO_TX_PACKETS |
11433 STATION_INFO_TX_RETRIES |
11434 STATION_INFO_TX_FAILED;
11435
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011436 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11437 TRACE_CODE_HDD_CFG80211_GET_STA,
11438 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011439 EXIT();
11440 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011441}
11442
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011443static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11444 u8* mac, struct station_info *sinfo)
11445{
11446 int ret;
11447
11448 vos_ssr_protect(__func__);
11449 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11450 vos_ssr_unprotect(__func__);
11451
11452 return ret;
11453}
11454
11455static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011456 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011457{
11458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011459 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011461 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011462
Jeff Johnsone7245742012-09-05 17:12:55 -070011463 ENTER();
11464
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 if (NULL == pAdapter)
11466 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 return -ENODEV;
11469 }
11470
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011471 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11472 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11473 pAdapter->sessionId, timeout));
11474
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011475 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011476 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011477
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011478 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011479 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11481 "%s: HDD context is not valid", __func__);
11482 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011483 }
11484
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011485 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11486 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11487 (pHddCtx->cfg_ini->fhostArpOffload) &&
11488 (eConnectionState_Associated ==
11489 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11490 {
Amar Singhald53568e2013-09-26 11:03:45 -070011491
11492 hddLog(VOS_TRACE_LEVEL_INFO,
11493 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011494 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011495 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11496 {
11497 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011498 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011499 __func__, vos_status);
11500 }
11501 }
11502
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 /**The get power cmd from the supplicant gets updated by the nl only
11504 *on successful execution of the function call
11505 *we are oppositely mapped w.r.t mode in the driver
11506 **/
11507 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11508
Kiet Lam94fd2922014-06-18 19:12:43 -070011509 if (!mode)
11510 {
11511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11512 "%s: DHCP start indicated through power save", __func__);
11513
11514 pHddCtx->btCoexModeSet = TRUE;
11515 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11516 pAdapter->sessionId);
11517 }
11518 else
11519 {
11520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11521 "%s: DHCP stop indicated through power save", __func__);
11522
11523 pHddCtx->btCoexModeSet = FALSE;
11524 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11525 pAdapter->sessionId);
11526 }
11527
Jeff Johnsone7245742012-09-05 17:12:55 -070011528 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 if (VOS_STATUS_E_FAILURE == vos_status)
11530 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11532 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 return -EINVAL;
11534 }
11535 return 0;
11536}
11537
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011538static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11539 struct net_device *dev, bool mode, int timeout)
11540{
11541 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011542
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011543 vos_ssr_protect(__func__);
11544 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11545 vos_ssr_unprotect(__func__);
11546
11547 return ret;
11548}
Jeff Johnson295189b2012-06-20 16:38:30 -070011549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11550static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11551 struct net_device *netdev,
11552 u8 key_index)
11553{
Jeff Johnsone7245742012-09-05 17:12:55 -070011554 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011555 return 0;
11556}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011557#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011558
11559#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11560static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11561 struct net_device *dev,
11562 struct ieee80211_txq_params *params)
11563{
Jeff Johnsone7245742012-09-05 17:12:55 -070011564 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 return 0;
11566}
11567#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11568static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11569 struct ieee80211_txq_params *params)
11570{
Jeff Johnsone7245742012-09-05 17:12:55 -070011571 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 return 0;
11573}
11574#endif //LINUX_VERSION_CODE
11575
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011576static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 struct net_device *dev, u8 *mac)
11578{
11579 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011580 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011581 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011582 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011583 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011584
Jeff Johnsone7245742012-09-05 17:12:55 -070011585 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011586
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011587 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 return -EINVAL;
11591 }
11592
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011593 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11594 TRACE_CODE_HDD_CFG80211_DEL_STA,
11595 pAdapter->sessionId, pAdapter->device_mode));
11596
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011597 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11598 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011599
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011600 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011601 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11603 "%s: HDD context is not valid", __func__);
11604 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011605 }
11606
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011608 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 )
11610 {
11611 if( NULL == mac )
11612 {
11613 v_U16_t i;
11614 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11615 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011616 if ((pAdapter->aStaInfo[i].isUsed) &&
11617 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 {
11619 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11620 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011621 "%s: Delete STA with MAC::"
11622 MAC_ADDRESS_STR,
11623 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011624 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11625 if (VOS_IS_STATUS_SUCCESS(vos_status))
11626 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 }
11628 }
11629 }
11630 else
11631 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011632
11633 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11634 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11635 {
11636 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011637 "%s: Skip this DEL STA as this is not used::"
11638 MAC_ADDRESS_STR,
11639 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011640 return -ENOENT;
11641 }
11642
11643 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11644 {
11645 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011646 "%s: Skip this DEL STA as deauth is in progress::"
11647 MAC_ADDRESS_STR,
11648 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011649 return -ENOENT;
11650 }
11651
11652 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11653
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 hddLog(VOS_TRACE_LEVEL_INFO,
11655 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011656 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011658 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011659
11660 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11661 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11662 {
11663 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11664 hddLog(VOS_TRACE_LEVEL_INFO,
11665 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011666 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011667 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011668 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011669 return -ENOENT;
11670 }
11671
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 }
11673 }
11674
11675 EXIT();
11676
11677 return 0;
11678}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011679static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11680 struct net_device *dev, u8 *mac)
11681{
11682 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011683
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011684 vos_ssr_protect(__func__);
11685 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11686 vos_ssr_unprotect(__func__);
11687
11688 return ret;
11689}
11690
11691static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011692 struct net_device *dev, u8 *mac, struct station_parameters *params)
11693{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011695 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011696#ifdef FEATURE_WLAN_TDLS
11697 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011698 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011699
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11701 TRACE_CODE_HDD_CFG80211_ADD_STA,
11702 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011703 mask = params->sta_flags_mask;
11704
11705 set = params->sta_flags_set;
11706
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011707#ifdef WLAN_FEATURE_TDLS_DEBUG
11708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11709 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11710 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11711#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011712
11713 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11714 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011715 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011716 }
11717 }
11718#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011719 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011720}
11721
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011722static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11723 struct net_device *dev, u8 *mac, struct station_parameters *params)
11724{
11725 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011726
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011727 vos_ssr_protect(__func__);
11728 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11729 vos_ssr_unprotect(__func__);
11730
11731 return ret;
11732}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011733#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011734
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011735static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011736 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011737{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011738 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011739 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011740 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011741 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011742 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011743 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011744 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011745 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011746 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11747 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011748
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011749 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011750 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011753 return -EINVAL;
11754 }
11755
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011756 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11757 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011758
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011759 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011760 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11762 "%s: HDD context is not valid", __func__);
11763 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011764 }
11765
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011767 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011768 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011769
Agarwal Ashish3da95242014-05-21 14:57:17 +053011770 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011771 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011772 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011773 pmksa->bssid, WNI_CFG_BSSID_LEN))
11774 {
11775 /* BSSID matched previous entry. Overwrite it. */
11776 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011777 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011778 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011779 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011781 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011782 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011783 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011784 dump_bssid(pmksa->bssid);
11785 dump_pmkid(halHandle, pmksa->pmkid);
11786 break;
11787 }
11788 }
11789
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011790 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011791 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011792
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011793 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011794 {
11795 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011796 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011798 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011800 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011801 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11802 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011803 dump_bssid(pmksa->bssid);
11804 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011805 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011806 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011807 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11808 pHddStaCtx->PMKIDCacheIndex++;
11809 else
11810 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011811 }
11812
11813
11814 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011815 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11816 __func__, pHddStaCtx->PMKIDCacheIndex );
11817
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011818 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011819 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011820 pHddStaCtx->PMKIDCache,
11821 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011822 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11823 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11824 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011825 return 0;
11826}
11827
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011828static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11829 struct cfg80211_pmksa *pmksa)
11830{
11831 int ret;
11832
11833 vos_ssr_protect(__func__);
11834 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11835 vos_ssr_unprotect(__func__);
11836
11837 return ret;
11838}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011839
Wilson Yang6507c4e2013-10-01 20:11:19 -070011840
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011841static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011842 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011843{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011844 tANI_U32 j=0;
11845 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011846 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011847 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011848 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011849 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011850 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011851
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011852 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11853 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011854
11855 /* Validate pAdapter */
11856 if (NULL == pAdapter)
11857 {
11858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11859 return -EINVAL;
11860 }
11861
11862 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11863 status = wlan_hdd_validate_context(pHddCtx);
11864
11865 if (0 != status)
11866 {
11867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11868 "%s: HDD context is not valid", __func__);
11869 return status;
11870 }
11871
11872 /*Retrieve halHandle*/
11873 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011875
11876 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011877 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011878 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011879 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11880 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011881 }
11882
11883 /*find the matching PMKSA entry from j=0 to (index-1),
11884 * and delete the matched one
11885 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011886 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011887 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011888 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011889 pmksa->bssid,
11890 WNI_CFG_BSSID_LEN))
11891 {
11892 /* BSSID matched entry */
11893 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011894 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011895 {
11896 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011897 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11898 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11899 VOS_MAC_ADDR_SIZE);
11900 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11901 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11902 CSR_RSN_PMKID_SIZE);
11903 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011904
11905 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011906 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11907 VOS_MAC_ADDR_SIZE);
11908 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11909 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011910 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011911 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011912 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011913 if (eHAL_STATUS_SUCCESS !=
11914 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011915 {
11916 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011917 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011918 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011919 }
11920
11921 dump_bssid(pmksa->bssid);
11922 dump_pmkid(halHandle,pmksa->pmkid);
11923
11924 break;
11925 }
11926 }
11927
11928 /* we compare all entries,but cannot find matching entry */
11929 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
11930 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011931 hddLog(VOS_TRACE_LEVEL_FATAL,
11932 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
11933 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011934 dump_bssid(pmksa->bssid);
11935 dump_pmkid(halHandle, pmksa->pmkid);
11936 return -EINVAL;
11937 }
Wilson Yangef657d32014-01-15 19:19:23 -080011938 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011939}
11940
Wilson Yang6507c4e2013-10-01 20:11:19 -070011941
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011942static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
11943 struct cfg80211_pmksa *pmksa)
11944{
11945 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011946
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011947 vos_ssr_protect(__func__);
11948 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
11949 vos_ssr_unprotect(__func__);
11950
11951 return ret;
11952
11953}
11954
11955static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011956{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011957 tANI_U32 j=0;
11958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011959 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011960 tHalHandle halHandle;
11961 hdd_context_t *pHddCtx;
11962 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080011963 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011964
11965 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
11966
11967 /* Validate pAdapter */
11968 if (NULL == pAdapter)
11969 {
11970 hddLog(VOS_TRACE_LEVEL_ERROR,
11971 "%s: Invalid Adapter" ,__func__);
11972 return -EINVAL;
11973 }
11974
11975 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11976 status = wlan_hdd_validate_context(pHddCtx);
11977
11978 if (0 != status)
11979 {
11980 hddLog(VOS_TRACE_LEVEL_ERROR,
11981 "%s: HDD context is not valid", __func__);
11982 return status;
11983 }
11984
11985 /*Retrieve halHandle*/
11986 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011987 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011988
11989 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011990 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011991 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053011992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053011993 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011994 }
11995
11996 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011997 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011998 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011999 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012000 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012001 if (eHAL_STATUS_SUCCESS !=
12002 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012003 {
12004 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12005 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012006 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012007 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012008 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012009 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12010 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12011 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012012
Agarwal Ashish3da95242014-05-21 14:57:17 +053012013 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012014 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012015}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012016
12017static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12018{
12019 int ret;
12020
12021 vos_ssr_protect(__func__);
12022 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12023 vos_ssr_unprotect(__func__);
12024
12025 return ret;
12026}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012027#endif
12028
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012029#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012030static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12031 struct net_device *dev,
12032 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012033{
12034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12035 hdd_station_ctx_t *pHddStaCtx;
12036
12037 if (NULL == pAdapter)
12038 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012040 return -ENODEV;
12041 }
12042
12043 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12044
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012045 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12046 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12047 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012048 // Added for debug on reception of Re-assoc Req.
12049 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12050 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012051 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012052 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012053 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012054 }
12055
12056#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012057 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012058 ftie->ie_len);
12059#endif
12060
12061 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012062 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12063 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012064 ftie->ie_len);
12065 return 0;
12066}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012067
12068static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12069 struct net_device *dev,
12070 struct cfg80211_update_ft_ies_params *ftie)
12071{
12072 int ret;
12073
12074 vos_ssr_protect(__func__);
12075 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12076 vos_ssr_unprotect(__func__);
12077
12078 return ret;
12079}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012080#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012081
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012082#ifdef FEATURE_WLAN_SCAN_PNO
12083
12084void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12085 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12086{
12087 int ret;
12088 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12089 hdd_context_t *pHddCtx;
12090
Nirav Shah80830bf2013-12-31 16:35:12 +053012091 ENTER();
12092
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012093 if (NULL == pAdapter)
12094 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012096 "%s: HDD adapter is Null", __func__);
12097 return ;
12098 }
12099
12100 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12101 if (NULL == pHddCtx)
12102 {
12103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12104 "%s: HDD context is Null!!!", __func__);
12105 return ;
12106 }
12107
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012108 spin_lock(&pHddCtx->schedScan_lock);
12109 if (TRUE == pHddCtx->isWiphySuspended)
12110 {
12111 pHddCtx->isSchedScanUpdatePending = TRUE;
12112 spin_unlock(&pHddCtx->schedScan_lock);
12113 hddLog(VOS_TRACE_LEVEL_INFO,
12114 "%s: Update cfg80211 scan database after it resume", __func__);
12115 return ;
12116 }
12117 spin_unlock(&pHddCtx->schedScan_lock);
12118
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012119 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12120
12121 if (0 > ret)
12122 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12123
12124 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12126 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012127}
12128
12129/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012130 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012131 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012132 */
12133static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12134{
12135 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12136 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012137 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012138 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12139 int status = 0;
12140 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12141
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012142 /* The current firmware design does not allow PNO during any
12143 * active sessions. Hence, determine the active sessions
12144 * and return a failure.
12145 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012146 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12147 {
12148 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012149 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012150
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012151 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12152 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12153 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12154 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12155 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12156 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012157 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012158 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012159 }
12160 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12161 pAdapterNode = pNext;
12162 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012163 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012164}
12165
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012166void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12167{
12168 hdd_adapter_t *pAdapter = callbackContext;
12169 hdd_context_t *pHddCtx;
12170
12171 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12172 {
12173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12174 FL("Invalid adapter or adapter has invalid magic"));
12175 return;
12176 }
12177
12178 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12179 if (0 != wlan_hdd_validate_context(pHddCtx))
12180 {
12181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12182 FL("HDD context is not valid"));
12183 return;
12184 }
12185
12186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12187 FL("PNO enable response status = %d"), status);
12188
12189 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12190 complete(&pAdapter->pno_comp_var);
12191}
12192
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012193/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012194 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12195 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012196 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012197static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012198 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12199{
12200 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12201 tpSirPNOScanReq pPnoRequest = NULL;
12202 hdd_context_t *pHddCtx;
12203 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012204 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012205 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12206 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012207 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12208 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012209 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012210
12211 if (NULL == pAdapter)
12212 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012214 "%s: HDD adapter is Null", __func__);
12215 return -ENODEV;
12216 }
12217
12218 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012219 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012220
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012221 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012222 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12224 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012225 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012226 }
12227
12228 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12229 if (NULL == hHal)
12230 {
12231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12232 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012233 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012234 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012235
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012236 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012237 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012238 {
12239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12240 "%s: aborting the existing scan is unsuccessfull", __func__);
12241 return -EBUSY;
12242 }
12243
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012244 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012245 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012247 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012248 return -EBUSY;
12249 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012250
c_hpothu37f21312014-04-09 21:49:54 +053012251 if (TRUE == pHddCtx->isPnoEnable)
12252 {
12253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12254 FL("already PNO is enabled"));
12255 return -EBUSY;
12256 }
12257 pHddCtx->isPnoEnable = TRUE;
12258
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012259 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12260 if (NULL == pPnoRequest)
12261 {
12262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12263 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012264 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012265 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012266 }
12267
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012268 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012269 pPnoRequest->enable = 1; /*Enable PNO */
12270 pPnoRequest->ucNetworksCount = request->n_match_sets;
12271
12272 if (( !pPnoRequest->ucNetworksCount ) ||
12273 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12274 {
12275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012276 "%s: Network input is not correct %d Max Network supported is %d",
12277 __func__, pPnoRequest->ucNetworksCount,
12278 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012279 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012280 goto error;
12281 }
12282
12283 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12284 {
12285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012286 "%s: Incorrect number of channels %d",
12287 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012288 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012289 goto error;
12290 }
12291
12292 /* Framework provides one set of channels(all)
12293 * common for all saved profile */
12294 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12295 channels_allowed, &num_channels_allowed))
12296 {
12297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12298 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012299 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012300 goto error;
12301 }
12302 /* Checking each channel against allowed channel list */
12303 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012304 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012305 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012306 char chList [(request->n_channels*5)+1];
12307 int len;
12308 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012309 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012310 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012311 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012312 if (request->channels[i]->hw_value == channels_allowed[indx])
12313 {
12314 valid_ch[num_ch++] = request->channels[i]->hw_value;
12315 len += snprintf(chList+len, 5, "%d ",
12316 request->channels[i]->hw_value);
12317 break ;
12318 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012319 }
12320 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012321 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12322 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012323
12324 /* Filling per profile params */
12325 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12326 {
12327 pPnoRequest->aNetworks[i].ssId.length =
12328 request->match_sets[i].ssid.ssid_len;
12329
12330 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12331 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12332 {
12333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012334 "%s: SSID Len %d is not correct for network %d",
12335 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012336 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012337 goto error;
12338 }
12339
12340 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12341 request->match_sets[i].ssid.ssid,
12342 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12344 "%s: SSID of network %d is %s ", __func__,
12345 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012346 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12347 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12348 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12349
12350 /*Copying list of valid channel into request */
12351 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12352 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12353
12354 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12355 }
12356
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012358 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012359 if ((0 < request->ie_len) && (NULL != request->ie))
12360 {
12361 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12362 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12363 pPnoRequest->us24GProbeTemplateLen);
12364
12365 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12366 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12367 pPnoRequest->us5GProbeTemplateLen);
12368 }
12369
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012370 /* Driver gets only one time interval which is hardcoded in
12371 * supplicant for 10000ms. Taking power consumption into account 6 timers
12372 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12373 * 80,160,320 secs. And number of scan cycle for each timer
12374 * is configurable through INI param gPNOScanTimerRepeatValue.
12375 * If it is set to 0 only one timer will be used and PNO scan cycle
12376 * will be repeated after each interval specified by supplicant
12377 * till PNO is disabled.
12378 */
12379 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12380 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12381 else
12382 pPnoRequest->scanTimers.ucScanTimersCount =
12383 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12384
12385 tempInterval = (request->interval)/1000;
12386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12387 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12388 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12389 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12390 {
12391 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12392 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12393 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12394 tempInterval *= 2;
12395 }
12396 //Repeat last timer until pno disabled.
12397 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12398
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012399 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012400
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012401 INIT_COMPLETION(pAdapter->pno_comp_var);
12402 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12403 pPnoRequest->callbackContext = pAdapter;
12404 pAdapter->pno_req_status = 0;
12405
Nirav Shah80830bf2013-12-31 16:35:12 +053012406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12407 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12408 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12409 pPnoRequest->scanTimers.ucScanTimersCount);
12410
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012411 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12412 pPnoRequest, pAdapter->sessionId,
12413 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12414 if (eHAL_STATUS_SUCCESS != status)
12415 {
12416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012417 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012418 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012419 goto error;
12420 }
12421
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012422 ret = wait_for_completion_timeout(
12423 &pAdapter->pno_comp_var,
12424 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12425 if (0 >= ret)
12426 {
12427 // Did not receive the response for PNO enable in time.
12428 // Assuming the PNO enable was success.
12429 // Returning error from here, because we timeout, results
12430 // in side effect of Wifi (Wifi Setting) not to work.
12431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12432 FL("Timed out waiting for PNO to be Enabled"));
12433 ret = 0;
12434 goto error;
12435 }
12436
12437 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012438 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012439
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012440error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12442 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012443 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012444 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012445 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012446}
12447
12448/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012449 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12450 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012451 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012452static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12453 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12454{
12455 int ret;
12456
12457 vos_ssr_protect(__func__);
12458 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12459 vos_ssr_unprotect(__func__);
12460
12461 return ret;
12462}
12463
12464/*
12465 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12466 * Function to disable PNO
12467 */
12468static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012469 struct net_device *dev)
12470{
12471 eHalStatus status = eHAL_STATUS_FAILURE;
12472 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12473 hdd_context_t *pHddCtx;
12474 tHalHandle hHal;
12475 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012476 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012477
12478 ENTER();
12479
12480 if (NULL == pAdapter)
12481 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012483 "%s: HDD adapter is Null", __func__);
12484 return -ENODEV;
12485 }
12486
12487 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012488
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012489 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012490 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012492 "%s: HDD context is Null", __func__);
12493 return -ENODEV;
12494 }
12495
12496 /* The return 0 is intentional when isLogpInProgress and
12497 * isLoadUnloadInProgress. We did observe a crash due to a return of
12498 * failure in sched_scan_stop , especially for a case where the unload
12499 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12500 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12501 * success. If it returns a failure , then its next invocation due to the
12502 * clean up of the second interface will have the dev pointer corresponding
12503 * to the first one leading to a crash.
12504 */
12505 if (pHddCtx->isLogpInProgress)
12506 {
12507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12508 "%s: LOGP in Progress. Ignore!!!", __func__);
12509 return ret;
12510 }
12511
Mihir Shete18156292014-03-11 15:38:30 +053012512 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012513 {
12514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12515 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12516 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012517 }
12518
12519 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12520 if (NULL == hHal)
12521 {
12522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12523 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012524 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012525 }
12526
12527 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12528 if (NULL == pPnoRequest)
12529 {
12530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12531 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012532 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012533 }
12534
12535 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12536 pPnoRequest->enable = 0; /* Disable PNO */
12537 pPnoRequest->ucNetworksCount = 0;
12538
12539 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12540 pAdapter->sessionId,
12541 NULL, pAdapter);
12542 if (eHAL_STATUS_SUCCESS != status)
12543 {
12544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12545 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012546 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012547 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012548 }
c_hpothu37f21312014-04-09 21:49:54 +053012549 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012550
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012551error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012553 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012554 vos_mem_free(pPnoRequest);
12555
12556 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012557 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012558}
12559
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012560/*
12561 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12562 * NL interface to disable PNO
12563 */
12564static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12565 struct net_device *dev)
12566{
12567 int ret;
12568
12569 vos_ssr_protect(__func__);
12570 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12571 vos_ssr_unprotect(__func__);
12572
12573 return ret;
12574}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012575#endif /*FEATURE_WLAN_SCAN_PNO*/
12576
12577
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012578#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012579#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012580static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12581 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012582 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12583#else
12584static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12585 u8 *peer, u8 action_code, u8 dialog_token,
12586 u16 status_code, const u8 *buf, size_t len)
12587#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012588{
12589
12590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12591 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012592 u8 peerMac[6];
12593 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012594 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012595 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012596 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012597#if !(TDLS_MGMT_VERSION2)
12598 u32 peer_capability = 0;
12599#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012600 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012601
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12603 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12604 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012605 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012606 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012608 "Invalid arguments");
12609 return -EINVAL;
12610 }
12611
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012612 if (pHddCtx->isLogpInProgress)
12613 {
12614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12615 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012616 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012617 return -EBUSY;
12618 }
12619
Hoonki Lee27511902013-03-14 18:19:06 -070012620 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012621 {
Hoonki Lee27511902013-03-14 18:19:06 -070012622 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12623 "%s: TDLS mode is disabled OR not enabled in FW."
12624 MAC_ADDRESS_STR " action %d declined.",
12625 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012626 return -ENOTSUPP;
12627 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012628
Hoonki Lee27511902013-03-14 18:19:06 -070012629 /* other than teardown frame, other mgmt frames are not sent if disabled */
12630 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12631 {
12632 /* if tdls_mode is disabled to respond to peer's request */
12633 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12634 {
12635 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12636 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012637 " TDLS mode is disabled. action %d declined.",
12638 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012639
12640 return -ENOTSUPP;
12641 }
12642 }
12643
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012644 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12645 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012646 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012647 {
12648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012649 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012650 " TDLS setup is ongoing. action %d declined.",
12651 __func__, MAC_ADDR_ARRAY(peer), action_code);
12652 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012653 }
12654 }
12655
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012656 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12657 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012658 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012659 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12660 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012661 {
12662 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12663 we return error code at 'add_station()'. Hence we have this
12664 check again in addtion to add_station().
12665 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012666 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012667 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12669 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012670 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12671 __func__, MAC_ADDR_ARRAY(peer), action_code,
12672 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012673 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012674 }
12675 else
12676 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012677 /* maximum reached. tweak to send error code to peer and return
12678 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012679 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12681 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012682 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12683 __func__, MAC_ADDR_ARRAY(peer), status_code,
12684 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012685 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012686 /* fall through to send setup resp with failure status
12687 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012688 }
12689 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012690 else
12691 {
12692 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012693 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012694 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012695 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012697 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12698 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012699 return -EPERM;
12700 }
12701 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012702 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012703 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012704
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012705#ifdef WLAN_FEATURE_TDLS_DEBUG
12706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012707 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012708 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12709 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012710#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012711
Hoonki Leea34dd892013-02-05 22:56:02 -080012712 /*Except teardown responder will not be used so just make 0*/
12713 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012714 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012715 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012716
12717 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012718 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012719
12720 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12721 responder = pTdlsPeer->is_responder;
12722 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012723 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012725 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012726 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12727 dialog_token, status_code, len);
12728 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012729 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012730 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012731
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012732 /* For explicit trigger of DIS_REQ come out of BMPS for
12733 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012734 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012735 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12736 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012737 {
12738 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12739 {
12740 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012741 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012742 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12743 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012744 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12745 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012746 }
12747
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012748 /* make sure doesn't call send_mgmt() while it is pending */
12749 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12750 {
12751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012752 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012753 __func__, MAC_ADDR_ARRAY(peer), action_code);
12754 return -EBUSY;
12755 }
12756
12757 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012758 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12759
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012760 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012761 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012762
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012763 if (VOS_STATUS_SUCCESS != status)
12764 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12766 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012767 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012768 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012769 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012770 }
12771
Hoonki Leed37cbb32013-04-20 00:31:14 -070012772 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12773 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12774
12775 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012776 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012778 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012779 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012780 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012781
12782 if (pHddCtx->isLogpInProgress)
12783 {
12784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12785 "%s: LOGP in Progress. Ignore!!!", __func__);
12786 return -EAGAIN;
12787 }
12788
Hoonki Leed37cbb32013-04-20 00:31:14 -070012789 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012790 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012791 }
12792
Gopichand Nakkala05922802013-03-14 12:23:19 -070012793 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012794 {
12795 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012796 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012797 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012798
Hoonki Leea34dd892013-02-05 22:56:02 -080012799 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12800 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012801 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012802 }
12803 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12804 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012805 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012806 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012807
12808 return 0;
12809}
12810
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012811static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012812 u8 *peer, enum nl80211_tdls_operation oper)
12813{
12814 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12815 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012816 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012817 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012818
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012819 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12820 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12821 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012822 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012823 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012825 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012826 return -EINVAL;
12827 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012828
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012829 status = wlan_hdd_validate_context(pHddCtx);
12830
12831 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12834 "%s: HDD context is not valid", __func__);
12835 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012836 }
12837
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012838
12839 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012840 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012841 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012843 "TDLS Disabled in INI OR not enabled in FW. "
12844 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012845 return -ENOTSUPP;
12846 }
12847
12848 switch (oper) {
12849 case NL80211_TDLS_ENABLE_LINK:
12850 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012851 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012852 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012853 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012854
Sunil Dutt41de4e22013-11-14 18:09:02 +053012855 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12856
12857 if ( NULL == pTdlsPeer ) {
12858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12859 " (oper %d) not exsting. ignored",
12860 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12861 return -EINVAL;
12862 }
12863
12864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12865 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12866 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12867 "NL80211_TDLS_ENABLE_LINK");
12868
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012869 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12870 {
12871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12872 MAC_ADDRESS_STR " failed",
12873 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12874 return -EINVAL;
12875 }
12876
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012877 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012878 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012879 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012880
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012881 if (0 != wlan_hdd_tdls_get_link_establish_params(
12882 pAdapter, peer,&tdlsLinkEstablishParams)) {
12883 return -EINVAL;
12884 }
12885 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012886
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012887 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12888 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12889 /* Send TDLS peer UAPSD capabilities to the firmware and
12890 * register with the TL on after the response for this operation
12891 * is received .
12892 */
12893 ret = wait_for_completion_interruptible_timeout(
12894 &pAdapter->tdls_link_establish_req_comp,
12895 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12896 if (ret <= 0)
12897 {
12898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12899 "%s: Link Establish Request Faled Status %ld",
12900 __func__, ret);
12901 return -EINVAL;
12902 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012903 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012904 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012905 /* Mark TDLS client Authenticated .*/
12906 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12907 pTdlsPeer->staId,
12908 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012909 if (VOS_STATUS_SUCCESS == status)
12910 {
Hoonki Lee14621352013-04-16 17:51:19 -070012911 if (pTdlsPeer->is_responder == 0)
12912 {
12913 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
12914
12915 wlan_hdd_tdls_timer_restart(pAdapter,
12916 &pTdlsPeer->initiatorWaitTimeoutTimer,
12917 WAIT_TIME_TDLS_INITIATOR);
12918 /* suspend initiator TX until it receives direct packet from the
12919 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
12920 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12921 &staId, NULL);
12922 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012923 wlan_hdd_tdls_increment_peer_count(pAdapter);
12924 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012925 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012926
12927 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012928 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
12929 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012930 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012931 int ac;
12932 uint8 ucAc[4] = { WLANTL_AC_VO,
12933 WLANTL_AC_VI,
12934 WLANTL_AC_BK,
12935 WLANTL_AC_BE };
12936 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
12937 for(ac=0; ac < 4; ac++)
12938 {
12939 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12940 pTdlsPeer->staId, ucAc[ac],
12941 tlTid[ac], tlTid[ac], 0, 0,
12942 WLANTL_BI_DIR );
12943 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012944 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012945 }
12946
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012947 }
12948 break;
12949 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080012950 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053012951 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12952
12953 if ( NULL == pTdlsPeer ) {
12954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12955 " (oper %d) not exsting. ignored",
12956 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12957 return -EINVAL;
12958 }
12959
12960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12961 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12962 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12963 "NL80211_TDLS_DISABLE_LINK");
12964
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012965 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080012966 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012967 long status;
12968
12969 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
12970
Lee Hoonkic1262f22013-01-24 21:59:00 -080012971 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
12972 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012973
12974 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
12975 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
12976 if (status <= 0)
12977 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012978 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12980 "%s: Del station failed status %ld",
12981 __func__, status);
12982 return -EPERM;
12983 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012984 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080012985 }
12986 else
12987 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12989 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080012990 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012991 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012992 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012993 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053012994 {
12995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12996 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
12997 __func__, MAC_ADDR_ARRAY(peer));
12998
12999 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13000 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13001
13002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13003 " %s TDLS External control and Implicit Trigger not enabled ",
13004 __func__);
13005 return -ENOTSUPP;
13006 }
13007
Sunil Dutt41de4e22013-11-14 18:09:02 +053013008
13009 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13010
13011 if ( NULL == pTdlsPeer ) {
13012 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13013 " peer not exsting",
13014 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013015 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013016 }
13017 else {
13018 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13019 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13020 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013021
13022 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13023 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013024 break;
13025 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013026 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013027 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013028 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13030 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13031 __func__, MAC_ADDR_ARRAY(peer));
13032
13033 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13034 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13035
13036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13037 " %s TDLS External control and Implicit Trigger not enabled ",
13038 __func__);
13039 return -ENOTSUPP;
13040 }
13041
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013042 /* To cater the requirement of establishing the TDLS link
13043 * irrespective of the data traffic , get an entry of TDLS peer.
13044 */
13045 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13046 if (pTdlsPeer == NULL) {
13047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13048 "%s: peer " MAC_ADDRESS_STR " not existing",
13049 __func__, MAC_ADDR_ARRAY(peer));
13050 return -EINVAL;
13051 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013052
13053 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13054
13055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13056 " %s TDLS Add Force Peer Failed",
13057 __func__);
13058 return -EINVAL;
13059 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013060 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013061 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013062 case NL80211_TDLS_DISCOVERY_REQ:
13063 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13065 "%s: We don't support in-driver setup/teardown/discovery "
13066 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013067 return -ENOTSUPP;
13068 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13070 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013071 return -ENOTSUPP;
13072 }
13073 return 0;
13074}
Chilam NG571c65a2013-01-19 12:27:36 +053013075
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013076static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13077 u8 *peer, enum nl80211_tdls_operation oper)
13078{
13079 int ret;
13080
13081 vos_ssr_protect(__func__);
13082 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13083 vos_ssr_unprotect(__func__);
13084
13085 return ret;
13086}
13087
Chilam NG571c65a2013-01-19 12:27:36 +053013088int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13089 struct net_device *dev, u8 *peer)
13090{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013091 hddLog(VOS_TRACE_LEVEL_INFO,
13092 "tdls send discover req: "MAC_ADDRESS_STR,
13093 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013094
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013095#if TDLS_MGMT_VERSION2
13096 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13097 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13098#else
Chilam NG571c65a2013-01-19 12:27:36 +053013099 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13100 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013101#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013102}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013103#endif
13104
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013105#ifdef WLAN_FEATURE_GTK_OFFLOAD
13106/*
13107 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13108 * Callback rountine called upon receiving response for
13109 * get offload info
13110 */
13111void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13112 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13113{
13114
13115 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013116 tANI_U8 tempReplayCounter[8];
13117 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013118
13119 ENTER();
13120
13121 if (NULL == pAdapter)
13122 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013124 "%s: HDD adapter is Null", __func__);
13125 return ;
13126 }
13127
13128 if (NULL == pGtkOffloadGetInfoRsp)
13129 {
13130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13131 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13132 return ;
13133 }
13134
13135 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13136 {
13137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13138 "%s: wlan Failed to get replay counter value",
13139 __func__);
13140 return ;
13141 }
13142
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013143 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13144 /* Update replay counter */
13145 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13146 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13147
13148 {
13149 /* changing from little to big endian since supplicant
13150 * works on big endian format
13151 */
13152 int i;
13153 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13154
13155 for (i = 0; i < 8; i++)
13156 {
13157 tempReplayCounter[7-i] = (tANI_U8)p[i];
13158 }
13159 }
13160
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013161 /* Update replay counter to NL */
13162 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013163 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013164}
13165
13166/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013167 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013168 * This function is used to offload GTK rekeying job to the firmware.
13169 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013170int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013171 struct cfg80211_gtk_rekey_data *data)
13172{
13173 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13174 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13175 hdd_station_ctx_t *pHddStaCtx;
13176 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013177 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013178 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013179 eHalStatus status = eHAL_STATUS_FAILURE;
13180
13181 ENTER();
13182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013183
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013184 if (NULL == pAdapter)
13185 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013187 "%s: HDD adapter is Null", __func__);
13188 return -ENODEV;
13189 }
13190
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013191 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13192 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13193 pAdapter->sessionId, pAdapter->device_mode));
13194
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013195 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013196
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013197 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013198 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13200 "%s: HDD context is not valid", __func__);
13201 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013202 }
13203
13204 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13205 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13206 if (NULL == hHal)
13207 {
13208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13209 "%s: HAL context is Null!!!", __func__);
13210 return -EAGAIN;
13211 }
13212
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013213 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13214 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13215 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13216 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013217 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013218 {
13219 /* changing from big to little endian since driver
13220 * works on little endian format
13221 */
13222 tANI_U8 *p =
13223 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13224 int i;
13225
13226 for (i = 0; i < 8; i++)
13227 {
13228 p[7-i] = data->replay_ctr[i];
13229 }
13230 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013231
13232 if (TRUE == pHddCtx->hdd_wlan_suspended)
13233 {
13234 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013235 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13236 sizeof (tSirGtkOffloadParams));
13237 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013238 pAdapter->sessionId);
13239
13240 if (eHAL_STATUS_SUCCESS != status)
13241 {
13242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13243 "%s: sme_SetGTKOffload failed, returned %d",
13244 __func__, status);
13245 return status;
13246 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13248 "%s: sme_SetGTKOffload successfull", __func__);
13249 }
13250 else
13251 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13253 "%s: wlan not suspended GTKOffload request is stored",
13254 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013255 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013256
13257 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013258}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013259
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013260int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13261 struct cfg80211_gtk_rekey_data *data)
13262{
13263 int ret;
13264
13265 vos_ssr_protect(__func__);
13266 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13267 vos_ssr_unprotect(__func__);
13268
13269 return ret;
13270}
13271#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013272/*
13273 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13274 * This function is used to set access control policy
13275 */
13276static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13277 struct net_device *dev, const struct cfg80211_acl_data *params)
13278{
13279 int i;
13280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13281 hdd_hostapd_state_t *pHostapdState;
13282 tsap_Config_t *pConfig;
13283 v_CONTEXT_t pVosContext = NULL;
13284 hdd_context_t *pHddCtx;
13285 int status;
13286
13287 ENTER();
13288
13289 if (NULL == pAdapter)
13290 {
13291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13292 "%s: HDD adapter is Null", __func__);
13293 return -ENODEV;
13294 }
13295
13296 if (NULL == params)
13297 {
13298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13299 "%s: params is Null", __func__);
13300 return -EINVAL;
13301 }
13302
13303 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13304 status = wlan_hdd_validate_context(pHddCtx);
13305
13306 if (0 != status)
13307 {
13308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13309 "%s: HDD context is not valid", __func__);
13310 return status;
13311 }
13312
13313 pVosContext = pHddCtx->pvosContext;
13314 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13315
13316 if (NULL == pHostapdState)
13317 {
13318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13319 "%s: pHostapdState is Null", __func__);
13320 return -EINVAL;
13321 }
13322
13323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13324 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13325
13326 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13327 {
13328 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13329
13330 /* default value */
13331 pConfig->num_accept_mac = 0;
13332 pConfig->num_deny_mac = 0;
13333
13334 /**
13335 * access control policy
13336 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13337 * listed in hostapd.deny file.
13338 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13339 * listed in hostapd.accept file.
13340 */
13341 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13342 {
13343 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13344 }
13345 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13346 {
13347 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13348 }
13349 else
13350 {
13351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13352 "%s:Acl Policy : %d is not supported",
13353 __func__, params->acl_policy);
13354 return -ENOTSUPP;
13355 }
13356
13357 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13358 {
13359 pConfig->num_accept_mac = params->n_acl_entries;
13360 for (i = 0; i < params->n_acl_entries; i++)
13361 {
13362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13363 "** Add ACL MAC entry %i in WhiletList :"
13364 MAC_ADDRESS_STR, i,
13365 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13366
13367 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13368 sizeof(qcmacaddr));
13369 }
13370 }
13371 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13372 {
13373 pConfig->num_deny_mac = params->n_acl_entries;
13374 for (i = 0; i < params->n_acl_entries; i++)
13375 {
13376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13377 "** Add ACL MAC entry %i in BlackList :"
13378 MAC_ADDRESS_STR, i,
13379 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13380
13381 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13382 sizeof(qcmacaddr));
13383 }
13384 }
13385
13386 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13387 {
13388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13389 "%s: SAP Set Mac Acl fail", __func__);
13390 return -EINVAL;
13391 }
13392 }
13393 else
13394 {
13395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013396 "%s: Invalid device_mode = %s (%d)",
13397 __func__, hdd_device_modetoString(pAdapter->device_mode),
13398 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013399 return -EINVAL;
13400 }
13401
13402 return 0;
13403}
13404
Leo Chang9056f462013-08-01 19:21:11 -070013405#ifdef WLAN_NL80211_TESTMODE
13406#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013407void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013408(
13409 void *pAdapter,
13410 void *indCont
13411)
13412{
Leo Changd9df8aa2013-09-26 13:32:26 -070013413 tSirLPHBInd *lphbInd;
13414 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013415 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013416
13417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013418 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013419
c_hpothu73f35e62014-04-18 13:40:08 +053013420 if (pAdapter == NULL)
13421 {
13422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13423 "%s: pAdapter is NULL\n",__func__);
13424 return;
13425 }
13426
Leo Chang9056f462013-08-01 19:21:11 -070013427 if (NULL == indCont)
13428 {
13429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013430 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013431 return;
13432 }
13433
c_hpothu73f35e62014-04-18 13:40:08 +053013434 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013435 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013436 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013437 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013438 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013439 GFP_ATOMIC);
13440 if (!skb)
13441 {
13442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13443 "LPHB timeout, NL buffer alloc fail");
13444 return;
13445 }
13446
Leo Changac3ba772013-10-07 09:47:04 -070013447 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013448 {
13449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13450 "WLAN_HDD_TM_ATTR_CMD put fail");
13451 goto nla_put_failure;
13452 }
Leo Changac3ba772013-10-07 09:47:04 -070013453 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013454 {
13455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13456 "WLAN_HDD_TM_ATTR_TYPE put fail");
13457 goto nla_put_failure;
13458 }
Leo Changac3ba772013-10-07 09:47:04 -070013459 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013460 sizeof(tSirLPHBInd), lphbInd))
13461 {
13462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13463 "WLAN_HDD_TM_ATTR_DATA put fail");
13464 goto nla_put_failure;
13465 }
Leo Chang9056f462013-08-01 19:21:11 -070013466 cfg80211_testmode_event(skb, GFP_ATOMIC);
13467 return;
13468
13469nla_put_failure:
13470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13471 "NLA Put fail");
13472 kfree_skb(skb);
13473
13474 return;
13475}
13476#endif /* FEATURE_WLAN_LPHB */
13477
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013478static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013479{
13480 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13481 int err = 0;
13482#ifdef FEATURE_WLAN_LPHB
13483 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013484 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013485#endif /* FEATURE_WLAN_LPHB */
13486
13487 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13488 if (err)
13489 {
13490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13491 "%s Testmode INV ATTR", __func__);
13492 return err;
13493 }
13494
13495 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13496 {
13497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13498 "%s Testmode INV CMD", __func__);
13499 return -EINVAL;
13500 }
13501
13502 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13503 {
13504#ifdef FEATURE_WLAN_LPHB
13505 /* Low Power Heartbeat configuration request */
13506 case WLAN_HDD_TM_CMD_WLAN_HB:
13507 {
13508 int buf_len;
13509 void *buf;
13510 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013511 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013512
13513 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13514 {
13515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13516 "%s Testmode INV DATA", __func__);
13517 return -EINVAL;
13518 }
13519
13520 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13521 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013522
13523 hb_params_temp =(tSirLPHBReq *)buf;
13524 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13525 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13526 return -EINVAL;
13527
Leo Chang9056f462013-08-01 19:21:11 -070013528 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13529 if (NULL == hb_params)
13530 {
13531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13532 "%s Request Buffer Alloc Fail", __func__);
13533 return -EINVAL;
13534 }
13535
13536 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013537 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13538 hb_params,
13539 wlan_hdd_cfg80211_lphb_ind_handler);
13540 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013541 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13543 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013544 vos_mem_free(hb_params);
13545 }
Leo Chang9056f462013-08-01 19:21:11 -070013546 return 0;
13547 }
13548#endif /* FEATURE_WLAN_LPHB */
13549 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13551 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013552 return -EOPNOTSUPP;
13553 }
13554
13555 return err;
13556}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013557
13558static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13559{
13560 int ret;
13561
13562 vos_ssr_protect(__func__);
13563 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13564 vos_ssr_unprotect(__func__);
13565
13566 return ret;
13567}
Leo Chang9056f462013-08-01 19:21:11 -070013568#endif /* CONFIG_NL80211_TESTMODE */
13569
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013570static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013571 struct net_device *dev,
13572 int idx, struct survey_info *survey)
13573{
13574 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13575 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013576 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013577 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013578 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013579 v_S7_t snr,rssi;
13580 int status, i, j, filled = 0;
13581
13582 ENTER();
13583
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013584 if (NULL == pAdapter)
13585 {
13586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13587 "%s: HDD adapter is Null", __func__);
13588 return -ENODEV;
13589 }
13590
13591 if (NULL == wiphy)
13592 {
13593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13594 "%s: wiphy is Null", __func__);
13595 return -ENODEV;
13596 }
13597
13598 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13599 status = wlan_hdd_validate_context(pHddCtx);
13600
13601 if (0 != status)
13602 {
13603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13604 "%s: HDD context is not valid", __func__);
13605 return status;
13606 }
13607
Mihir Sheted9072e02013-08-21 17:02:29 +053013608 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13609
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013610 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013611 0 != pAdapter->survey_idx ||
13612 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013613 {
13614 /* The survey dump ops when implemented completely is expected to
13615 * return a survey of all channels and the ops is called by the
13616 * kernel with incremental values of the argument 'idx' till it
13617 * returns -ENONET. But we can only support the survey for the
13618 * operating channel for now. survey_idx is used to track
13619 * that the ops is called only once and then return -ENONET for
13620 * the next iteration
13621 */
13622 pAdapter->survey_idx = 0;
13623 return -ENONET;
13624 }
13625
13626 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13627
13628 wlan_hdd_get_snr(pAdapter, &snr);
13629 wlan_hdd_get_rssi(pAdapter, &rssi);
13630
13631 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13632 hdd_wlan_get_freq(channel, &freq);
13633
13634
13635 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13636 {
13637 if (NULL == wiphy->bands[i])
13638 {
13639 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13640 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13641 continue;
13642 }
13643
13644 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13645 {
13646 struct ieee80211_supported_band *band = wiphy->bands[i];
13647
13648 if (band->channels[j].center_freq == (v_U16_t)freq)
13649 {
13650 survey->channel = &band->channels[j];
13651 /* The Rx BDs contain SNR values in dB for the received frames
13652 * while the supplicant expects noise. So we calculate and
13653 * return the value of noise (dBm)
13654 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13655 */
13656 survey->noise = rssi - snr;
13657 survey->filled = SURVEY_INFO_NOISE_DBM;
13658 filled = 1;
13659 }
13660 }
13661 }
13662
13663 if (filled)
13664 pAdapter->survey_idx = 1;
13665 else
13666 {
13667 pAdapter->survey_idx = 0;
13668 return -ENONET;
13669 }
13670
13671 return 0;
13672}
13673
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013674static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13675 struct net_device *dev,
13676 int idx, struct survey_info *survey)
13677{
13678 int ret;
13679
13680 vos_ssr_protect(__func__);
13681 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13682 vos_ssr_unprotect(__func__);
13683
13684 return ret;
13685}
13686
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013687/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013688 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013689 * this is called when cfg80211 driver resume
13690 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13691 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013692int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013693{
13694 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13695 hdd_adapter_t *pAdapter;
13696 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13697 VOS_STATUS status = VOS_STATUS_SUCCESS;
13698
13699 ENTER();
13700
13701 if ( NULL == pHddCtx )
13702 {
13703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13704 "%s: HddCtx validation failed", __func__);
13705 return 0;
13706 }
13707
13708 if (pHddCtx->isLogpInProgress)
13709 {
13710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13711 "%s: LOGP in Progress. Ignore!!!", __func__);
13712 return 0;
13713 }
13714
Mihir Shete18156292014-03-11 15:38:30 +053013715 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013716 {
13717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13718 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13719 return 0;
13720 }
13721
13722 spin_lock(&pHddCtx->schedScan_lock);
13723 pHddCtx->isWiphySuspended = FALSE;
13724 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13725 {
13726 spin_unlock(&pHddCtx->schedScan_lock);
13727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13728 "%s: Return resume is not due to PNO indication", __func__);
13729 return 0;
13730 }
13731 // Reset flag to avoid updatating cfg80211 data old results again
13732 pHddCtx->isSchedScanUpdatePending = FALSE;
13733 spin_unlock(&pHddCtx->schedScan_lock);
13734
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013735
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013736 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13737
13738 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13739 {
13740 pAdapter = pAdapterNode->pAdapter;
13741 if ( (NULL != pAdapter) &&
13742 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13743 {
13744 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013745 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13747 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013748 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013749 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013750 {
13751 /* Acquire wakelock to handle the case where APP's tries to
13752 * suspend immediately after updating the scan results. Whis
13753 * results in app's is in suspended state and not able to
13754 * process the connect request to AP
13755 */
13756 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013757 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013758 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013759
13760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13761 "%s : cfg80211 scan result database updated", __func__);
13762
13763 return 0;
13764
13765 }
13766 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13767 pAdapterNode = pNext;
13768 }
13769
13770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13771 "%s: Failed to find Adapter", __func__);
13772 return 0;
13773}
13774
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013775int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13776{
13777 int ret;
13778
13779 vos_ssr_protect(__func__);
13780 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13781 vos_ssr_unprotect(__func__);
13782
13783 return ret;
13784}
13785
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013786/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013787 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013788 * this is called when cfg80211 driver suspends
13789 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013790int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013791 struct cfg80211_wowlan *wow)
13792{
13793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13794
13795 ENTER();
13796 if (NULL == pHddCtx)
13797 {
13798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13799 "%s: HddCtx validation failed", __func__);
13800 return 0;
13801 }
13802
13803 pHddCtx->isWiphySuspended = TRUE;
13804
13805 EXIT();
13806
13807 return 0;
13808}
13809
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013810int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13811 struct cfg80211_wowlan *wow)
13812{
13813 int ret;
13814
13815 vos_ssr_protect(__func__);
13816 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13817 vos_ssr_unprotect(__func__);
13818
13819 return ret;
13820}
Jeff Johnson295189b2012-06-20 16:38:30 -070013821/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013822static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013823{
13824 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13825 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13826 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13827 .change_station = wlan_hdd_change_station,
13828#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13829 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13830 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13831 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013832#else
13833 .start_ap = wlan_hdd_cfg80211_start_ap,
13834 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13835 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013836#endif
13837 .change_bss = wlan_hdd_cfg80211_change_bss,
13838 .add_key = wlan_hdd_cfg80211_add_key,
13839 .get_key = wlan_hdd_cfg80211_get_key,
13840 .del_key = wlan_hdd_cfg80211_del_key,
13841 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013842#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013844#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 .scan = wlan_hdd_cfg80211_scan,
13846 .connect = wlan_hdd_cfg80211_connect,
13847 .disconnect = wlan_hdd_cfg80211_disconnect,
13848 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13849 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13850 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13851 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13852 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13854 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013855 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13857 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13858 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13859 .set_txq_params = wlan_hdd_set_txq_params,
13860#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 .get_station = wlan_hdd_cfg80211_get_station,
13862 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13863 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013864 .add_station = wlan_hdd_cfg80211_add_station,
13865#ifdef FEATURE_WLAN_LFR
13866 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13867 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13868 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13869#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013870#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13871 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13872#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013873#ifdef FEATURE_WLAN_TDLS
13874 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13875 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13876#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013877#ifdef WLAN_FEATURE_GTK_OFFLOAD
13878 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13879#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013880#ifdef FEATURE_WLAN_SCAN_PNO
13881 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13882 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13883#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013884 .resume = wlan_hdd_cfg80211_resume_wlan,
13885 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013886 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013887#ifdef WLAN_NL80211_TESTMODE
13888 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13889#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013890 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013891};
13892