blob: 4b1c10eaa6916e99661ff64c075dc08fdc9300a0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, 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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**========================================================================
43
44 \file wlan_hdd_cfg80211.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 21/12/09 Ashwani Created module.
69
70 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
71 Ganesh K
72 ==========================================================================*/
73
74#ifdef CONFIG_CFG80211
75
76#include <linux/version.h>
77#include <linux/module.h>
78#include <linux/kernel.h>
79#include <linux/init.h>
80#include <linux/wireless.h>
81#include <wlan_hdd_includes.h>
82#include <net/arp.h>
83#include <net/cfg80211.h>
84#include <linux/wireless.h>
85#include <wlan_hdd_wowl.h>
86#include <aniGlobal.h>
87#include "ccmApi.h"
88#include "sirParams.h"
89#include "dot11f.h"
90#include "wlan_hdd_assoc.h"
91#include "wlan_hdd_wext.h"
92#include "sme_Api.h"
93#include "wlan_hdd_p2p.h"
94#include "wlan_hdd_cfg80211.h"
95#include "wlan_hdd_hostapd.h"
96#include "sapInternal.h"
97#include "wlan_hdd_softap_tx_rx.h"
98#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053099#include "wlan_hdd_assoc.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#ifdef WLAN_BTAMP_FEATURE
101#include "bap_hdd_misc.h"
102#endif
103#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800104#ifdef FEATURE_WLAN_TDLS
105#include "wlan_hdd_tdls.h"
106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define g_mode_rates_size (12)
109#define a_mode_rates_size (8)
110#define FREQ_BASE_80211G (2407)
111#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700112#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
114 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
115
116#define HDD2GHZCHAN(freq, chan, flag) { \
117 .band = IEEE80211_BAND_2GHZ, \
118 .center_freq = (freq), \
119 .hw_value = (chan),\
120 .flags = (flag), \
121 .max_antenna_gain = 0 ,\
122 .max_power = 30, \
123}
124
125#define HDD5GHZCHAN(freq, chan, flag) { \
126 .band = IEEE80211_BAND_5GHZ, \
127 .center_freq = (freq), \
128 .hw_value = (chan),\
129 .flags = (flag), \
130 .max_antenna_gain = 0 ,\
131 .max_power = 30, \
132}
133
134#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
135{\
136 .bitrate = rate, \
137 .hw_value = rate_id, \
138 .flags = flag, \
139}
140
141static const u32 hdd_cipher_suites[] =
142{
143 WLAN_CIPHER_SUITE_WEP40,
144 WLAN_CIPHER_SUITE_WEP104,
145 WLAN_CIPHER_SUITE_TKIP,
146#ifdef FEATURE_WLAN_CCX
147#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
148 WLAN_CIPHER_SUITE_KRK,
149 WLAN_CIPHER_SUITE_CCMP,
150#else
151 WLAN_CIPHER_SUITE_CCMP,
152#endif
153#ifdef FEATURE_WLAN_WAPI
154 WLAN_CIPHER_SUITE_SMS4,
155#endif
156};
157
158static inline int is_broadcast_ether_addr(const u8 *addr)
159{
160 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
161 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
162}
163
164static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
165{
166 HDD2GHZCHAN(2412, 1, 0) ,
167 HDD2GHZCHAN(2417, 2, 0) ,
168 HDD2GHZCHAN(2422, 3, 0) ,
169 HDD2GHZCHAN(2427, 4, 0) ,
170 HDD2GHZCHAN(2432, 5, 0) ,
171 HDD2GHZCHAN(2437, 6, 0) ,
172 HDD2GHZCHAN(2442, 7, 0) ,
173 HDD2GHZCHAN(2447, 8, 0) ,
174 HDD2GHZCHAN(2452, 9, 0) ,
175 HDD2GHZCHAN(2457, 10, 0) ,
176 HDD2GHZCHAN(2462, 11, 0) ,
177 HDD2GHZCHAN(2467, 12, 0) ,
178 HDD2GHZCHAN(2472, 13, 0) ,
179 HDD2GHZCHAN(2484, 14, 0) ,
180};
181
182#ifdef WLAN_FEATURE_P2P
183static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
184{
185 HDD2GHZCHAN(2412, 1, 0) ,
186 HDD2GHZCHAN(2437, 6, 0) ,
187 HDD2GHZCHAN(2462, 11, 0) ,
188};
189#endif
190
191static struct ieee80211_channel hdd_channels_5_GHZ[] =
192{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700193 HDD5GHZCHAN(4920, 240, 0) ,
194 HDD5GHZCHAN(4940, 244, 0) ,
195 HDD5GHZCHAN(4960, 248, 0) ,
196 HDD5GHZCHAN(4980, 252, 0) ,
197 HDD5GHZCHAN(5040, 208, 0) ,
198 HDD5GHZCHAN(5060, 212, 0) ,
199 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700200 HDD5GHZCHAN(5180, 36, 0) ,
201 HDD5GHZCHAN(5200, 40, 0) ,
202 HDD5GHZCHAN(5220, 44, 0) ,
203 HDD5GHZCHAN(5240, 48, 0) ,
204 HDD5GHZCHAN(5260, 52, 0) ,
205 HDD5GHZCHAN(5280, 56, 0) ,
206 HDD5GHZCHAN(5300, 60, 0) ,
207 HDD5GHZCHAN(5320, 64, 0) ,
208 HDD5GHZCHAN(5500,100, 0) ,
209 HDD5GHZCHAN(5520,104, 0) ,
210 HDD5GHZCHAN(5540,108, 0) ,
211 HDD5GHZCHAN(5560,112, 0) ,
212 HDD5GHZCHAN(5580,116, 0) ,
213 HDD5GHZCHAN(5600,120, 0) ,
214 HDD5GHZCHAN(5620,124, 0) ,
215 HDD5GHZCHAN(5640,128, 0) ,
216 HDD5GHZCHAN(5660,132, 0) ,
217 HDD5GHZCHAN(5680,136, 0) ,
218 HDD5GHZCHAN(5700,140, 0) ,
219 HDD5GHZCHAN(5745,149, 0) ,
220 HDD5GHZCHAN(5765,153, 0) ,
221 HDD5GHZCHAN(5785,157, 0) ,
222 HDD5GHZCHAN(5805,161, 0) ,
223 HDD5GHZCHAN(5825,165, 0) ,
224};
225
226static struct ieee80211_rate g_mode_rates[] =
227{
228 HDD_G_MODE_RATETAB(10, 0x1, 0),
229 HDD_G_MODE_RATETAB(20, 0x2, 0),
230 HDD_G_MODE_RATETAB(55, 0x4, 0),
231 HDD_G_MODE_RATETAB(110, 0x8, 0),
232 HDD_G_MODE_RATETAB(60, 0x10, 0),
233 HDD_G_MODE_RATETAB(90, 0x20, 0),
234 HDD_G_MODE_RATETAB(120, 0x40, 0),
235 HDD_G_MODE_RATETAB(180, 0x80, 0),
236 HDD_G_MODE_RATETAB(240, 0x100, 0),
237 HDD_G_MODE_RATETAB(360, 0x200, 0),
238 HDD_G_MODE_RATETAB(480, 0x400, 0),
239 HDD_G_MODE_RATETAB(540, 0x800, 0),
240};
241
242static struct ieee80211_rate a_mode_rates[] =
243{
244 HDD_G_MODE_RATETAB(60, 0x10, 0),
245 HDD_G_MODE_RATETAB(90, 0x20, 0),
246 HDD_G_MODE_RATETAB(120, 0x40, 0),
247 HDD_G_MODE_RATETAB(180, 0x80, 0),
248 HDD_G_MODE_RATETAB(240, 0x100, 0),
249 HDD_G_MODE_RATETAB(360, 0x200, 0),
250 HDD_G_MODE_RATETAB(480, 0x400, 0),
251 HDD_G_MODE_RATETAB(540, 0x800, 0),
252};
253
254static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
255{
256 .channels = hdd_channels_2_4_GHZ,
257 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
258 .band = IEEE80211_BAND_2GHZ,
259 .bitrates = g_mode_rates,
260 .n_bitrates = g_mode_rates_size,
261 .ht_cap.ht_supported = 1,
262 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
263 | IEEE80211_HT_CAP_GRN_FLD
264 | IEEE80211_HT_CAP_DSSSCCK40
265 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
266 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
267 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
268 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
269 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
270 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
271};
272
273#ifdef WLAN_FEATURE_P2P
274static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
275{
276 .channels = hdd_social_channels_2_4_GHZ,
277 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
278 .band = IEEE80211_BAND_2GHZ,
279 .bitrates = g_mode_rates,
280 .n_bitrates = g_mode_rates_size,
281 .ht_cap.ht_supported = 1,
282 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
283 | IEEE80211_HT_CAP_GRN_FLD
284 | IEEE80211_HT_CAP_DSSSCCK40
285 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
286 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
287 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
288 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
289 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
290 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
291};
292#endif
293
294static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
295{
296 .channels = hdd_channels_5_GHZ,
297 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
298 .band = IEEE80211_BAND_5GHZ,
299 .bitrates = a_mode_rates,
300 .n_bitrates = a_mode_rates_size,
301 .ht_cap.ht_supported = 1,
302 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
303 | IEEE80211_HT_CAP_GRN_FLD
304 | IEEE80211_HT_CAP_DSSSCCK40
305 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
306 | IEEE80211_HT_CAP_SGI_40
307 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
315/* This structure contain information what kind of frame are expected in
316 TX/RX direction for each kind of interface */
317static const struct ieee80211_txrx_stypes
318wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
319 [NL80211_IFTYPE_STATION] = {
320 .tx = 0xffff,
321 .rx = BIT(SIR_MAC_MGMT_ACTION) |
322 BIT(SIR_MAC_MGMT_PROBE_REQ),
323 },
324 [NL80211_IFTYPE_AP] = {
325 .tx = 0xffff,
326 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
327 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
328 BIT(SIR_MAC_MGMT_PROBE_REQ) |
329 BIT(SIR_MAC_MGMT_DISASSOC) |
330 BIT(SIR_MAC_MGMT_AUTH) |
331 BIT(SIR_MAC_MGMT_DEAUTH) |
332 BIT(SIR_MAC_MGMT_ACTION),
333 },
334#ifdef WLAN_FEATURE_P2P
335 [NL80211_IFTYPE_P2P_CLIENT] = {
336 .tx = 0xffff,
337 .rx = BIT(SIR_MAC_MGMT_ACTION) |
338 BIT(SIR_MAC_MGMT_PROBE_REQ),
339 },
340 [NL80211_IFTYPE_P2P_GO] = {
341 /* This is also same as for SoftAP */
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
351#endif
352};
353
354static struct cfg80211_ops wlan_hdd_cfg80211_ops;
355
356/* Data rate 100KBPS based on IE Index */
357struct index_data_rate_type
358{
359 v_U8_t beacon_rate_index;
360 v_U16_t supported_rate[4];
361};
362
363/* 11B, 11G Rate table include Basic rate and Extended rate
364 The IDX field is the rate index
365 The HI field is the rate when RSSI is strong or being ignored
366 (in this case we report actual rate)
367 The MID field is the rate when RSSI is moderate
368 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
369 The LO field is the rate when RSSI is low
370 (in this case we don't report rates, actual current rate used)
371 */
372static const struct
373{
374 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700375 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700376} supported_data_rate[] =
377{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700378/* IDX HI HM LM LO (RSSI-based index */
379 {2, { 10, 10, 10, 0}},
380 {4, { 20, 20, 10, 0}},
381 {11, { 55, 20, 10, 0}},
382 {12, { 60, 55, 20, 0}},
383 {18, { 90, 55, 20, 0}},
384 {22, {110, 55, 20, 0}},
385 {24, {120, 90, 60, 0}},
386 {36, {180, 120, 60, 0}},
387 {44, {220, 180, 60, 0}},
388 {48, {240, 180, 90, 0}},
389 {66, {330, 180, 90, 0}},
390 {72, {360, 240, 90, 0}},
391 {96, {480, 240, 120, 0}},
392 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700393};
394
395/* MCS Based rate table */
396static struct index_data_rate_type supported_mcs_rate[] =
397{
398/* MCS L20 L40 S20 S40 */
399 {0, {65, 135, 72, 150}},
400 {1, {130, 270, 144, 300}},
401 {2, {195, 405, 217, 450}},
402 {3, {260, 540, 289, 600}},
403 {4, {390, 810, 433, 900}},
404 {5, {520, 1080, 578, 1200}},
405 {6, {585, 1215, 650, 1350}},
406 {7, {650, 1350, 722, 1500}}
407};
408
409extern struct net_device_ops net_ops_struct;
410
411/*
412 * FUNCTION: wlan_hdd_cfg80211_init
413 * This function is called by hdd_wlan_startup()
414 * during initialization.
415 * This function is used to initialize and register wiphy structure.
416 */
417struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
418{
419 struct wiphy *wiphy;
420 ENTER();
421
422 /*
423 * Create wiphy device
424 */
425 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
426
427 if (!wiphy)
428 {
429 /* Print error and jump into err label and free the memory */
430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
431 return NULL;
432 }
433
434 return wiphy;
435}
436
437/*
438 * FUNCTION: wlan_hdd_cfg80211_update_band
439 * This function is called from the supplicant through a
440 * private ioctl to change the band value
441 */
442int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
443{
Jeff Johnsone7245742012-09-05 17:12:55 -0700444 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700445 switch(eBand)
446 {
447 case eCSR_BAND_24:
448 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
449 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
450 break;
451 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700452#ifdef WLAN_FEATURE_P2P
453 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
454#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700457 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
458 break;
459 case eCSR_BAND_ALL:
460 default:
461 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
462 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
463 }
464 return 0;
465}
466/*
467 * FUNCTION: wlan_hdd_cfg80211_init
468 * This function is called by hdd_wlan_startup()
469 * during initialization.
470 * This function is used to initialize and register wiphy structure.
471 */
472int wlan_hdd_cfg80211_register(struct device *dev,
473 struct wiphy *wiphy,
474 hdd_config_t *pCfg
475 )
476{
Jeff Johnsone7245742012-09-05 17:12:55 -0700477 ENTER();
478
Jeff Johnson295189b2012-06-20 16:38:30 -0700479 /* Now bind the underlying wlan device with wiphy */
480 set_wiphy_dev(wiphy, dev);
481
482 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
483
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700484 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700485
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700487 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
488 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
489 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700490 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700491#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800492#ifdef FEATURE_WLAN_TDLS
493 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
494 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
495#endif
496
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700497 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
498 driver can still register regulatory callback and
499 it will get CRDA setting in wiphy->band[], but
500 driver need to determine what to do with both
501 regulatory settings */
502 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504 wiphy->max_scan_ssids = MAX_SCAN_SSID;
505
506 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
507
508 /* Supports STATION & AD-HOC modes right now */
509 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
510 | BIT(NL80211_IFTYPE_ADHOC)
511#ifdef WLAN_FEATURE_P2P
512 | BIT(NL80211_IFTYPE_P2P_CLIENT)
513 | BIT(NL80211_IFTYPE_P2P_GO)
514#endif
515 | BIT(NL80211_IFTYPE_AP);
516
517 /* Before registering we need to update the ht capabilitied based
518 * on ini values*/
519 if( !pCfg->ShortGI20MhzEnable )
520 {
521 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
522 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
523 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
524 }
525
526 if( !pCfg->ShortGI40MhzEnable )
527 {
528 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
529 }
530
531 if( !pCfg->nChannelBondingMode5GHz )
532 {
533 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
534 }
535
536 /*Initialize band capability*/
537 switch(pCfg->nBandCapability)
538 {
539 case eCSR_BAND_24:
540 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
541 break;
542 case eCSR_BAND_5G:
543#ifdef WLAN_FEATURE_P2P
544 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
545#endif
546 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
547 break;
548 case eCSR_BAND_ALL:
549 default:
550 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
551 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
552 }
553 /*Initialise the supported cipher suite details*/
554 wiphy->cipher_suites = hdd_cipher_suites;
555 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
556
557 /*signal strength in mBm (100*dBm) */
558 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
559
560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
561#ifdef WLAN_FEATURE_P2P
562 wiphy->max_remain_on_channel_duration = 1000;
563#endif
564#endif
565
566 /* Register our wiphy dev with cfg80211 */
567 if (0 > wiphy_register(wiphy))
568 {
569 /* print eror */
570 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
571 return -EIO;
572 }
573
574 EXIT();
575 return 0;
576}
577
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700578/* In this function we will try to get default country code from crda.
579 If the gCrdaDefaultCountryCode is configured in ini file,
580 we will try to call user space crda to get the regulatory settings for
581 that country. We will timeout if we can't get it from crda.
582 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
583*/
584int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
585{
586 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
587 if (memcmp(pCfg->crdaDefaultCountryCode,
588 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
589 {
590 init_completion(&pHddCtx->driver_crda_req);
591 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
592 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
593 CRDA_WAIT_TIME);
594 }
595 return 0;
596}
597
Jeff Johnson295189b2012-06-20 16:38:30 -0700598/* In this function we will do all post VOS start initialization.
599 In this function we will register for all frame in which supplicant
600 is interested.
601*/
602void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
603{
604#ifdef WLAN_FEATURE_P2P
605 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
606 /* Register for all P2P action, public action etc frames */
607 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
608
Jeff Johnsone7245742012-09-05 17:12:55 -0700609 ENTER();
610
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 /* Right now we are registering these frame when driver is getting
612 initialized. Once we will move to 2.6.37 kernel, in which we have
613 frame register ops, we will move this code as a part of that */
614 /* GAS Initial Request */
615 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
616 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
617
618 /* GAS Initial Response */
619 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
620 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
621
622 /* GAS Comeback Request */
623 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
624 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
625
626 /* GAS Comeback Response */
627 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
628 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
629
630 /* P2P Public Action */
631 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
632 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
633 P2P_PUBLIC_ACTION_FRAME_SIZE );
634
635 /* P2P Action */
636 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
637 (v_U8_t*)P2P_ACTION_FRAME,
638 P2P_ACTION_FRAME_SIZE );
639#endif /* WLAN_FEATURE_P2P */
640}
641
642void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
643{
644#ifdef WLAN_FEATURE_P2P
645 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
646 /* Register for all P2P action, public action etc frames */
647 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
648
Jeff Johnsone7245742012-09-05 17:12:55 -0700649 ENTER();
650
Jeff Johnson295189b2012-06-20 16:38:30 -0700651 /* Right now we are registering these frame when driver is getting
652 initialized. Once we will move to 2.6.37 kernel, in which we have
653 frame register ops, we will move this code as a part of that */
654 /* GAS Initial Request */
655
656 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
657 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
658
659 /* GAS Initial Response */
660 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
661 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
662
663 /* GAS Comeback Request */
664 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
665 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
666
667 /* GAS Comeback Response */
668 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
669 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
670
671 /* P2P Public Action */
672 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
673 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
674 P2P_PUBLIC_ACTION_FRAME_SIZE );
675
676 /* P2P Action */
677 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
678 (v_U8_t*)P2P_ACTION_FRAME,
679 P2P_ACTION_FRAME_SIZE );
680#endif /* WLAN_FEATURE_P2P */
681}
682
683#ifdef FEATURE_WLAN_WAPI
684void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
685 const u8 *mac_addr, u8 *key , int key_Len)
686{
687 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
688 tCsrRoamSetKey setKey;
689 v_BOOL_t isConnected = TRUE;
690 int status = 0;
691 v_U32_t roamId= 0xFF;
692 tANI_U8 *pKeyPtr = NULL;
693 int n = 0;
694
695 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
696 __func__,pAdapter->device_mode);
697
698 setKey.keyId = key_index; // Store Key ID
699 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
700 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
701 setKey.paeRole = 0 ; // the PAE role
702 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
703 {
704 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
705 }
706 else
707 {
708 isConnected = hdd_connIsConnected(pHddStaCtx);
709 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
710 }
711 setKey.keyLength = key_Len;
712 pKeyPtr = setKey.Key;
713 memcpy( pKeyPtr, key, key_Len);
714
715 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
716 __func__, key_Len);
717 for (n = 0 ; n < key_Len; n++)
718 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
719 __func__,n,setKey.Key[n]);
720
721 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
722 if ( isConnected )
723 {
724 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
725 pAdapter->sessionId, &setKey, &roamId );
726 }
727 if ( status != 0 )
728 {
729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
730 "[%4d] sme_RoamSetKey returned ERROR status= %d",
731 __LINE__, status );
732 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
733 }
734}
735#endif /* FEATURE_WLAN_WAPI*/
736
737#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
738int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
739 beacon_data_t **ppBeacon,
740 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700741#else
742int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
743 beacon_data_t **ppBeacon,
744 struct cfg80211_beacon_data *params,
745 int dtim_period)
746#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700747{
748 int size;
749 beacon_data_t *beacon = NULL;
750 beacon_data_t *old = NULL;
751 int head_len,tail_len;
752
Jeff Johnsone7245742012-09-05 17:12:55 -0700753 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700754 if (params->head && !params->head_len)
755 return -EINVAL;
756
757 old = pAdapter->sessionCtx.ap.beacon;
758
759 if (!params->head && !old)
760 return -EINVAL;
761
762 if (params->tail && !params->tail_len)
763 return -EINVAL;
764
765#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
766 /* Kernel 3.0 is not updating dtim_period for set beacon */
767 if (!params->dtim_period)
768 return -EINVAL;
769#endif
770
771 if(params->head)
772 head_len = params->head_len;
773 else
774 head_len = old->head_len;
775
776 if(params->tail || !old)
777 tail_len = params->tail_len;
778 else
779 tail_len = old->tail_len;
780
781 size = sizeof(beacon_data_t) + head_len + tail_len;
782
783 beacon = kzalloc(size, GFP_KERNEL);
784
785 if( beacon == NULL )
786 return -ENOMEM;
787
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700788#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700789 if(params->dtim_period || !old )
790 beacon->dtim_period = params->dtim_period;
791 else
792 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700793#else
794 if(dtim_period || !old )
795 beacon->dtim_period = dtim_period;
796 else
797 beacon->dtim_period = old->dtim_period;
798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700799
800 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
801 beacon->tail = beacon->head + head_len;
802 beacon->head_len = head_len;
803 beacon->tail_len = tail_len;
804
805 if(params->head) {
806 memcpy (beacon->head,params->head,beacon->head_len);
807 }
808 else {
809 if(old)
810 memcpy (beacon->head,old->head,beacon->head_len);
811 }
812
813 if(params->tail) {
814 memcpy (beacon->tail,params->tail,beacon->tail_len);
815 }
816 else {
817 if(old)
818 memcpy (beacon->tail,old->tail,beacon->tail_len);
819 }
820
821 *ppBeacon = beacon;
822
823 kfree(old);
824
825 return 0;
826
827}
Jeff Johnson295189b2012-06-20 16:38:30 -0700828
829v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
830{
831 int left = length;
832 v_U8_t *ptr = pIes;
833 v_U8_t elem_id,elem_len;
834
835 while(left >= 2)
836 {
837 elem_id = ptr[0];
838 elem_len = ptr[1];
839 left -= 2;
840 if(elem_len > left)
841 {
842 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700843 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 eid,elem_len,left);
845 return NULL;
846 }
847 if (elem_id == eid)
848 {
849 return ptr;
850 }
851
852 left -= elem_len;
853 ptr += (elem_len + 2);
854 }
855 return NULL;
856}
857
Jeff Johnson295189b2012-06-20 16:38:30 -0700858/* Check if rate is 11g rate or not */
859static int wlan_hdd_rate_is_11g(u8 rate)
860{
861 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
862 u8 i;
863 for (i = 0; i < 8; i++)
864 {
865 if(rate == gRateArray[i])
866 return TRUE;
867 }
868 return FALSE;
869}
870
871/* Check for 11g rate and set proper 11g only mode */
872static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
873 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
874{
875 u8 i, num_rates = pIe[0];
876
877 pIe += 1;
878 for ( i = 0; i < num_rates; i++)
879 {
880 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
881 {
882 /* If rate set have 11g rate than change the mode to 11G */
883 *pSapHw_mode = eSAP_DOT11_MODE_11g;
884 if (pIe[i] & BASIC_RATE_MASK)
885 {
886 /* If we have 11g rate as basic rate, it means mode
887 is 11g only mode.
888 */
889 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
890 *pCheckRatesfor11g = FALSE;
891 }
892 }
893 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
894 {
895 *require_ht = TRUE;
896 }
897 }
898 return;
899}
900
901static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
902{
903 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
904 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
905 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
906 u8 checkRatesfor11g = TRUE;
907 u8 require_ht = FALSE;
908 u8 *pIe=NULL;
909
910 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
911
912 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
913 pBeacon->head_len, WLAN_EID_SUPP_RATES);
914 if (pIe != NULL)
915 {
916 pIe += 1;
917 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
918 &pConfig->SapHw_mode);
919 }
920
921 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
922 WLAN_EID_EXT_SUPP_RATES);
923 if (pIe != NULL)
924 {
925
926 pIe += 1;
927 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
928 &pConfig->SapHw_mode);
929 }
930
931 if( pConfig->channel > 14 )
932 {
933 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
934 }
935
936 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
937 WLAN_EID_HT_CAPABILITY);
938
939 if(pIe)
940 {
941 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
942 if(require_ht)
943 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
944 }
945}
946
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700947#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700948static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
949 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700950#else
951static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
952 struct cfg80211_beacon_data *params)
953#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700954{
955 v_U8_t *genie;
956 v_U8_t total_ielen = 0, ielen = 0;
957 v_U8_t *pIe = NULL;
958 v_U8_t addIE[1] = {0};
959 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -0700960 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700961
962 genie = vos_mem_malloc(MAX_GENIE_LEN);
963
964 if(genie == NULL) {
965
966 return -ENOMEM;
967 }
968
969 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
970
971 if(pIe)
972 {
973 /*Copy the wps IE*/
974 ielen = pIe[1] + 2;
975 if( ielen <=MAX_GENIE_LEN)
976 {
977 vos_mem_copy(genie, pIe, ielen);
978 }
979 else
980 {
981 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700982 ret = -EINVAL;
983 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -0700984 }
985 total_ielen = ielen;
986 }
987
988#ifdef WLAN_FEATURE_WFD
989 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
990
991 if(pIe)
992 {
993 ielen = pIe[1] + 2;
994 if(total_ielen + ielen <= MAX_GENIE_LEN) {
995 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
996 }
997 else {
998 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700999 ret = -EINVAL;
1000 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001001 }
1002 total_ielen += ielen;
1003 }
1004#endif
1005
1006#ifdef WLAN_FEATURE_P2P
1007 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1008
1009 if(pIe)
1010 {
1011 ielen = pIe[1] + 2;
1012 if(total_ielen + ielen <= MAX_GENIE_LEN)
1013 {
1014 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
1015 }
1016 else
1017 {
1018 hddLog( VOS_TRACE_LEVEL_ERROR,
1019 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001020 ret = -EINVAL;
1021 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001022 }
1023 total_ielen += ielen;
1024 }
1025#endif
1026
1027 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1028 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1029 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1030 {
1031 hddLog(LOGE,
1032 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001033 ret = -EINVAL;
1034 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 }
1036
1037 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1038 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1039 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1040 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1041 ==eHAL_STATUS_FAILURE)
1042 {
1043 hddLog(LOGE,
1044 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001045 ret = -EINVAL;
1046 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001047 }
1048
1049 // Added for ProResp IE
1050 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1051 {
1052 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1053 u8 probe_rsp_ie_len[3] = {0};
1054 u8 counter = 0;
1055 /* Check Probe Resp Length if it is greater then 255 then Store
1056 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1057 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1058 Store More then 255 bytes into One Variable.
1059 */
1060 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1061 {
1062 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1063 {
1064 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1065 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1066 }
1067 else
1068 {
1069 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1070 rem_probe_resp_ie_len = 0;
1071 }
1072 }
1073
1074 rem_probe_resp_ie_len = 0;
1075
1076 if (probe_rsp_ie_len[0] > 0)
1077 {
1078 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1079 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1080 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1081 probe_rsp_ie_len[0], NULL,
1082 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1083 {
1084 hddLog(LOGE,
1085 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001086 ret = -EINVAL;
1087 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001088 }
1089 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1090 }
1091
1092 if (probe_rsp_ie_len[1] > 0)
1093 {
1094 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1095 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1096 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1097 probe_rsp_ie_len[1], NULL,
1098 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1099 {
1100 hddLog(LOGE,
1101 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001102 ret = -EINVAL;
1103 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 }
1105 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1106 }
1107
1108 if (probe_rsp_ie_len[2] > 0)
1109 {
1110 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1111 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1112 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1113 probe_rsp_ie_len[2], NULL,
1114 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1115 {
1116 hddLog(LOGE,
1117 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001118 ret = -EINVAL;
1119 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 }
1121 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1122 }
1123
1124 if (probe_rsp_ie_len[1] == 0 )
1125 {
1126 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1127 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1128 eANI_BOOLEAN_FALSE) )
1129 {
1130 hddLog(LOGE,
1131 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1132 }
1133 }
1134
1135 if (probe_rsp_ie_len[2] == 0 )
1136 {
1137 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1138 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1139 eANI_BOOLEAN_FALSE) )
1140 {
1141 hddLog(LOGE,
1142 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1143 }
1144 }
1145
1146 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1147 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1148 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1149 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1150 == eHAL_STATUS_FAILURE)
1151 {
1152 hddLog(LOGE,
1153 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001154 ret = -EINVAL;
1155 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001156 }
1157 }
1158 else
1159 {
1160 // Reset WNI_CFG_PROBE_RSP Flags
1161 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1162
1163 hddLog(VOS_TRACE_LEVEL_INFO,
1164 "%s: No Probe Response IE received in set beacon",
1165 __func__);
1166 }
1167
1168 // Added for AssocResp IE
1169 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1170 {
1171 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1172 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1173 params->assocresp_ies_len, NULL,
1174 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1175 {
1176 hddLog(LOGE,
1177 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001178 ret = -EINVAL;
1179 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001180 }
1181
1182 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1183 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1184 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1185 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1186 == eHAL_STATUS_FAILURE)
1187 {
1188 hddLog(LOGE,
1189 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001190 ret = -EINVAL;
1191 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 }
1193 }
1194 else
1195 {
1196 hddLog(VOS_TRACE_LEVEL_INFO,
1197 "%s: No Assoc Response IE received in set beacon",
1198 __func__);
1199
1200 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1201 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1202 eANI_BOOLEAN_FALSE) )
1203 {
1204 hddLog(LOGE,
1205 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1206 }
1207 }
1208
Jeff Johnsone7245742012-09-05 17:12:55 -07001209done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001210 vos_mem_free(genie);
1211 return 0;
1212}
Jeff Johnson295189b2012-06-20 16:38:30 -07001213
1214/*
1215 * FUNCTION: wlan_hdd_validate_operation_channel
1216 * called by wlan_hdd_cfg80211_start_bss() and
1217 * wlan_hdd_cfg80211_set_channel()
1218 * This function validates whether given channel is part of valid
1219 * channel list.
1220 */
1221static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1222{
1223
1224 v_U32_t num_ch = 0;
1225 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1226 u32 indx = 0;
1227 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1228
1229 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1230
1231 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1232 valid_ch, &num_ch))
1233 {
1234 hddLog(VOS_TRACE_LEVEL_ERROR,
1235 "%s: failed to get valid channel list\n", __func__);
1236 return VOS_STATUS_E_FAILURE;
1237 }
1238
1239 for (indx = 0; indx < num_ch; indx++)
1240 {
1241 if (channel == valid_ch[indx])
1242 {
1243 break;
1244 }
1245 }
1246
1247 if (indx >= num_ch)
1248 {
1249 hddLog(VOS_TRACE_LEVEL_ERROR,
1250 "%s: Invalid Channel [%d] \n", __func__, channel);
1251 return VOS_STATUS_E_FAILURE;
1252 }
1253 return VOS_STATUS_SUCCESS;
1254
1255}
1256
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301257/*
1258 * FUNCTION: wlan_hdd_select_cbmode
1259 * called by wlan_hdd_cfg80211_start_bss() and
1260 * This function selects the cbmode based on primary channel
1261 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001262VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301263{
1264 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001265 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1266 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1267
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301268 if(
1269#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001270 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1271 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301272#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001273 SapHw_mode != eSAP_DOT11_MODE_11n &&
1274 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301275 )
1276 {
1277 return VOS_STATUS_SUCCESS;
1278 }
1279
1280 if (!pConfigIni->nChannelBondingMode5GHz) {
1281 return VOS_STATUS_SUCCESS;
1282 }
1283
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001284 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301285 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1286
1287 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1288
1289#ifdef WLAN_FEATURE_11AC
1290
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001291 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1292 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301293 {
1294 if ( channel== 36 || channel == 52 || channel == 100 ||
1295 channel == 116 || channel == 149 )
1296 {
1297 smeConfig.csrConfig.channelBondingMode5GHz =
1298 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1299 }
1300 else if ( channel == 40 || channel == 56 || channel == 104 ||
1301 channel == 120 || channel == 153 )
1302 {
1303 smeConfig.csrConfig.channelBondingMode5GHz =
1304 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1305 }
1306 else if ( channel == 44 || channel == 60 || channel == 108 ||
1307 channel == 124 || channel == 157 )
1308 {
1309 smeConfig.csrConfig.channelBondingMode5GHz =
1310 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1311 }
1312 else if ( channel == 48 || channel == 64 || channel == 112 ||
1313 channel == 128 || channel == 161 )
1314 {
1315 smeConfig.csrConfig.channelBondingMode5GHz =
1316 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1317 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301318 }
1319#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001320 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1321 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301322 {
1323 if ( channel== 40 || channel == 48 || channel == 56 ||
1324 channel == 64 || channel == 104 || channel == 112 ||
1325 channel == 120 || channel == 128 || channel == 136 ||
1326 channel == 144 || channel == 153 || channel == 161 )
1327 {
1328 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1329 }
1330 else if ( channel== 36 || channel == 44 || channel == 52 ||
1331 channel == 60 || channel == 100 || channel == 108 ||
1332 channel == 116 || channel == 124 || channel == 132 ||
1333 channel == 140 || channel == 149 || channel == 157 )
1334 {
1335 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1336 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301337 }
1338 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1339
1340 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1341 return VOS_STATUS_SUCCESS;
1342}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001343
Jeff Johnson295189b2012-06-20 16:38:30 -07001344#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1345static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1346 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001347#else
1348static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1349 struct cfg80211_beacon_data *params,
1350 const u8 *ssid, size_t ssid_len,
1351 enum nl80211_hidden_ssid hidden_ssid)
1352#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001353{
1354 tsap_Config_t *pConfig;
1355 beacon_data_t *pBeacon = NULL;
1356 struct ieee80211_mgmt *pMgmt_frame;
1357 v_U8_t *pIe=NULL;
1358 v_U16_t capab_info;
1359 eCsrAuthType RSNAuthType;
1360 eCsrEncryptionType RSNEncryptType;
1361 eCsrEncryptionType mcRSNEncryptType;
1362 int status = VOS_STATUS_SUCCESS;
1363 tpWLAN_SAPEventCB pSapEventCallback;
1364 hdd_hostapd_state_t *pHostapdState;
1365 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1366 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1367 struct qc_mac_acl_entry *acl_entry = NULL;
1368 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001369 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001370
1371 ENTER();
1372
1373 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1374
1375 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1376
1377 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1378
1379 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1380
1381 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1382
1383 //channel is already set in the set_channel Call back
1384 //pConfig->channel = pCommitConfig->channel;
1385
1386 /*Protection parameter to enable or disable*/
1387 pConfig->protEnabled =
1388 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1389
1390 pConfig->dtim_period = pBeacon->dtim_period;
1391
1392 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1393 pConfig->dtim_period);
1394
1395
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001396 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001397 {
1398 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001400 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001401 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001402 tANI_BOOLEAN restartNeeded;
1403 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1404 pConfig->ieee80211d = 1;
1405 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1406 sme_setRegInfo(hHal, pConfig->countryCode);
1407 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1408 /*
1409 * If auto channel is configured i.e. channel is 0,
1410 * so skip channel validation.
1411 */
1412 if( AUTO_CHANNEL_SELECT != pConfig->channel )
Jeff Johnson295189b2012-06-20 16:38:30 -07001413 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001414 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1418 return -EINVAL;
1419 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001421 /*
1422 * Validate the given channel range for the given country code
1423 */
1424 else
1425 {
Ng Chilamfc416462012-12-27 17:26:52 -08001426 if(1 != pHddCtx->is_dynamic_channel_range_set)
1427 {
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001428 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1429 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
Ng Chilamfc416462012-12-27 17:26:52 -08001430 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001431 }
Ng Chilamfc416462012-12-27 17:26:52 -08001432
1433 pHddCtx->is_dynamic_channel_range_set = 0;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001436 else
1437 {
1438 pConfig->ieee80211d = 0;
1439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001441 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001442 {
1443 pConfig->ieee80211d = 0;
1444 }
1445 pConfig->authType = eSAP_AUTO_SWITCH;
1446
1447 capab_info = pMgmt_frame->u.beacon.capab_info;
1448
1449 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1450 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1451
1452 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1453
1454 /*Set wps station to configured*/
1455 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1456
1457 if(pIe)
1458 {
1459 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1460 {
1461 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1462 return -EINVAL;
1463 }
1464 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1465 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001466 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001467 /* Check 15 bit of WPS IE as it contain information for wps state
1468 * WPS state
1469 */
1470 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1471 {
1472 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1473 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1474 {
1475 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1476 }
1477 }
1478 }
1479 else
1480 {
1481 pConfig->wps_state = SAP_WPS_DISABLED;
1482 }
1483 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1484
1485 pConfig->RSNWPAReqIELength = 0;
1486 pConfig->pRSNWPAReqIE = NULL;
1487 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1488 WLAN_EID_RSN);
1489 if(pIe && pIe[1])
1490 {
1491 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1492 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1493 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1494 /* The actual processing may eventually be more extensive than
1495 * this. Right now, just consume any PMKIDs that are sent in
1496 * by the app.
1497 * */
1498 status = hdd_softap_unpackIE(
1499 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1500 &RSNEncryptType,
1501 &mcRSNEncryptType,
1502 &RSNAuthType,
1503 pConfig->pRSNWPAReqIE[1]+2,
1504 pConfig->pRSNWPAReqIE );
1505
1506 if( VOS_STATUS_SUCCESS == status )
1507 {
1508 /* Now copy over all the security attributes you have
1509 * parsed out
1510 * */
1511 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1512 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1513 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1514 = RSNEncryptType;
1515 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1516 "EncryptionType = %d mcEncryptionType = %d\n"),
1517 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1518 }
1519 }
1520
1521 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1522 pBeacon->tail, pBeacon->tail_len);
1523
1524 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1525 {
1526 if (pConfig->pRSNWPAReqIE)
1527 {
1528 /*Mixed mode WPA/WPA2*/
1529 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1530 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1531 }
1532 else
1533 {
1534 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1535 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1536 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1537 status = hdd_softap_unpackIE(
1538 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1539 &RSNEncryptType,
1540 &mcRSNEncryptType,
1541 &RSNAuthType,
1542 pConfig->pRSNWPAReqIE[1]+2,
1543 pConfig->pRSNWPAReqIE );
1544
1545 if( VOS_STATUS_SUCCESS == status )
1546 {
1547 /* Now copy over all the security attributes you have
1548 * parsed out
1549 * */
1550 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1551 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1552 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1553 = RSNEncryptType;
1554 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1555 "EncryptionType = %d mcEncryptionType = %d\n"),
1556 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1557 }
1558 }
1559 }
1560
1561 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1562
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001563#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001564 if (params->ssid != NULL)
1565 {
1566 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1567 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1568 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1569 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1570 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001571#else
1572 if (ssid != NULL)
1573 {
1574 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1575 pConfig->SSIDinfo.ssid.length = ssid_len;
1576 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1577 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1578 }
1579#endif
1580
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 vos_mem_copy(pConfig->self_macaddr.bytes,
1582 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1583
1584 /* default value */
1585 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1586 pConfig->num_accept_mac = 0;
1587 pConfig->num_deny_mac = 0;
1588
1589 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1590 pBeacon->tail, pBeacon->tail_len);
1591
1592 /* pIe for black list is following form:
1593 type : 1 byte
1594 length : 1 byte
1595 OUI : 4 bytes
1596 acl type : 1 byte
1597 no of mac addr in black list: 1 byte
1598 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1599 */
1600 if ((pIe != NULL) && (pIe[1] != 0))
1601 {
1602 pConfig->SapMacaddr_acl = pIe[6];
1603 pConfig->num_deny_mac = pIe[7];
1604 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1605 pIe[6], pIe[7]);
1606 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1607 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1608 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1609 for (i = 0; i < pConfig->num_deny_mac; i++)
1610 {
1611 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1612 acl_entry++;
1613 }
1614 }
1615 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1616 pBeacon->tail, pBeacon->tail_len);
1617
1618 /* pIe for white list is following form:
1619 type : 1 byte
1620 length : 1 byte
1621 OUI : 4 bytes
1622 acl type : 1 byte
1623 no of mac addr in white list: 1 byte
1624 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1625 */
1626 if ((pIe != NULL) && (pIe[1] != 0))
1627 {
1628 pConfig->SapMacaddr_acl = pIe[6];
1629 pConfig->num_accept_mac = pIe[7];
1630 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1631 pIe[6], pIe[7]);
1632 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1633 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1634 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1635 for (i = 0; i < pConfig->num_accept_mac; i++)
1636 {
1637 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1638 acl_entry++;
1639 }
1640 }
1641 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1642
Jeff Johnsone7245742012-09-05 17:12:55 -07001643#ifdef WLAN_FEATURE_11AC
1644 if(((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1645 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1646 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) )
1647 {
1648 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1649 }
1650#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301651
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001652 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1653 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001654 // ht_capab is not what the name conveys,this is used for protection bitmap
1655 pConfig->ht_capab =
1656 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1657
1658 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1659 {
1660 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1661 return -EINVAL;
1662 }
1663
1664 //Uapsd Enabled Bit
1665 pConfig->UapsdEnable =
1666 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1667 //Enable OBSS protection
1668 pConfig->obssProtEnabled =
1669 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1670
1671 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1672 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1673 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1674 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1675 (int)pConfig->channel);
1676 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1677 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1678 pConfig->authType);
1679 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1680 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1681 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1682 pConfig->protEnabled, pConfig->obssProtEnabled);
1683
1684 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1685 {
1686 //Bss already started. just return.
1687 //TODO Probably it should update some beacon params.
1688 hddLog( LOGE, "Bss Already started...Ignore the request");
1689 EXIT();
1690 return 0;
1691 }
1692
1693 pConfig->persona = pHostapdAdapter->device_mode;
1694
1695 pSapEventCallback = hdd_hostapd_SAPEventCB;
1696 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1697 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1698 {
1699 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1700 return -EINVAL;
1701 }
1702
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001703 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001704 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1705
1706 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1707
1708 if (!VOS_IS_STATUS_SUCCESS(status))
1709 {
1710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1711 ("ERROR: HDD vos wait for single_event failed!!\n"));
1712 VOS_ASSERT(0);
1713 }
1714
1715 //Succesfully started Bss update the state bit.
1716 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1717
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001718#ifdef WLAN_FEATURE_P2P_DEBUG
1719 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1720 {
1721 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1722 {
1723 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1724 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001725 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001726 }
1727 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1728 {
1729 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1730 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001731 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001732 }
1733 }
1734#endif
1735
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 pHostapdState->bCommit = TRUE;
1737 EXIT();
1738
1739 return 0;
1740}
1741
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001742#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001743static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1744 struct net_device *dev,
1745 struct beacon_parameters *params)
1746{
1747 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1748 int status=VOS_STATUS_SUCCESS;
1749
1750 ENTER();
1751
1752 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1753
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001754 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1755 {
1756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1757 "%s:LOGP in Progress. Ignore!!!", __func__);
1758 return -EAGAIN;
1759 }
1760
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1762#ifdef WLAN_FEATURE_P2P
1763 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1764#endif
1765 )
1766 {
1767 beacon_data_t *old,*new;
1768
1769 old = pAdapter->sessionCtx.ap.beacon;
1770
1771 if (old)
1772 return -EALREADY;
1773
1774 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1775
1776 if(status != VOS_STATUS_SUCCESS)
1777 {
1778 hddLog(VOS_TRACE_LEVEL_FATAL,
1779 "%s:Error!!! Allocating the new beacon\n",__func__);
1780 return -EINVAL;
1781 }
1782
1783 pAdapter->sessionCtx.ap.beacon = new;
1784
1785 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1786 }
1787
1788 EXIT();
1789 return status;
1790}
1791
1792static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
1793 struct net_device *dev,
1794 struct beacon_parameters *params)
1795{
1796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1797 int status=VOS_STATUS_SUCCESS;
1798
1799 ENTER();
1800
1801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1802 __func__,pAdapter->device_mode);
1803
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001804 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1805 {
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1807 "%s:LOGP in Progress. Ignore!!!", __func__);
1808 return -EAGAIN;
1809 }
1810
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1812#ifdef WLAN_FEATURE_P2P
1813 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1814#endif
1815 )
1816 {
1817 beacon_data_t *old,*new;
1818
1819 old = pAdapter->sessionCtx.ap.beacon;
1820
1821 if (!old)
1822 return -ENOENT;
1823
1824 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1825
1826 if(status != VOS_STATUS_SUCCESS) {
1827 hddLog(VOS_TRACE_LEVEL_FATAL,
1828 "%s: Error!!! Allocating the new beacon\n",__func__);
1829 return -EINVAL;
1830 }
1831
1832 pAdapter->sessionCtx.ap.beacon = new;
1833
1834 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1835 }
1836
1837 EXIT();
1838 return status;
1839}
1840
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001841#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1842
1843#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001844static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
1845 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001846#else
1847static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
1848 struct net_device *dev)
1849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001850{
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001852 hdd_context_t *pHddCtx = NULL;
1853 hdd_scaninfo_t *pScanInfo = NULL;
1854 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 VOS_STATUS status = 0;
1856
1857 ENTER();
1858
1859 if (NULL == pAdapter)
1860 {
1861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001862 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 return -ENODEV;
1864 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001865 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1868 "%s:LOGP in Progress. Ignore!!!", __func__);
1869 return -EAGAIN;
1870 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001871
1872 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1873 if (NULL == pHddCtx)
1874 {
1875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001876 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001877 return -ENODEV;
1878 }
1879
1880 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
1881 if (NULL == staAdapter)
1882 {
1883 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
1884 if (NULL == staAdapter)
1885 {
1886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001887 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001888 return -ENODEV;
1889 }
1890 }
1891
1892 pScanInfo = &pHddCtx->scan_info;
1893
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1895 {
1896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1897 return -EAGAIN;
1898 }
1899
1900 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1901
1902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1903 __func__,pAdapter->device_mode);
1904
Jeff Johnsone7245742012-09-05 17:12:55 -07001905 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
1906 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001907 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07001908 hdd_abort_mac_scan(staAdapter->pHddCtx);
1909 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001910 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07001911 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
1912 if (!status)
1913 {
1914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08001915 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001916 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001917 VOS_ASSERT(pScanInfo->mScanPending);
1918 return 0;
1919 }
1920 }
1921
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1923#ifdef WLAN_FEATURE_P2P
1924 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1925#endif
1926 )
1927 {
1928 beacon_data_t *old;
1929
1930 old = pAdapter->sessionCtx.ap.beacon;
1931
1932 if (!old)
1933 return -ENOENT;
1934
1935#ifdef CONFIG_CFG80211
1936 hdd_cleanup_actionframe(pHddCtx, pAdapter);
1937#endif
1938
1939 mutex_lock(&pHddCtx->sap_lock);
1940 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
1941 {
1942 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
1943 {
1944 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1945
1946 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1947
1948 if (!VOS_IS_STATUS_SUCCESS(status))
1949 {
1950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1951 ("ERROR: HDD vos wait for single_event failed!!\n"));
1952 VOS_ASSERT(0);
1953 }
1954 }
1955 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
1956 }
1957 mutex_unlock(&pHddCtx->sap_lock);
1958
1959 if(status != VOS_STATUS_SUCCESS)
1960 {
1961 hddLog(VOS_TRACE_LEVEL_FATAL,
1962 "%s:Error!!! Stopping the BSS\n",__func__);
1963 return -EINVAL;
1964 }
1965
1966 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1967 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
1968 ==eHAL_STATUS_FAILURE)
1969 {
1970 hddLog(LOGE,
1971 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
1972 }
1973
1974 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1975 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1976 eANI_BOOLEAN_FALSE) )
1977 {
1978 hddLog(LOGE,
1979 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1980 }
1981
1982 // Reset WNI_CFG_PROBE_RSP Flags
1983 wlan_hdd_reset_prob_rspies(pAdapter);
1984
1985 pAdapter->sessionCtx.ap.beacon = NULL;
1986 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001987#ifdef WLAN_FEATURE_P2P_DEBUG
1988 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
1989 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
1990 {
1991 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
1992 "GO got removed");
1993 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
1994 }
1995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 }
1997 EXIT();
1998 return status;
1999}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002000
2001#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2002
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302003static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2004 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002005 struct cfg80211_ap_settings *params)
2006{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302007 hdd_adapter_t *pAdapter;
2008 hdd_context_t *pHddCtx;
2009 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002010
2011 ENTER();
2012
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302013 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002014 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2016 "%s: Device is Null", __func__);
2017 return -ENODEV;
2018 }
2019
2020 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2021 if (NULL == pAdapter)
2022 {
2023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2024 "%s: HDD adapter is Null", __func__);
2025 return -ENODEV;
2026 }
2027
2028 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2029 {
2030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2031 "%s: HDD adapter magic is invalid", __func__);
2032 return -ENODEV;
2033 }
2034
2035 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2036 if (NULL == pHddCtx)
2037 {
2038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2039 "%s: HDD context is Null", __func__);
2040 return -ENODEV;
2041 }
2042
2043 if (pHddCtx->isLogpInProgress)
2044 {
2045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2046 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002047 return -EAGAIN;
2048 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302049
2050 if (pHddCtx->isLoadUnloadInProgress)
2051 {
2052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2053 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2054 return -EAGAIN;
2055 }
2056
2057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2058 __func__, pAdapter->device_mode);
2059
2060 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002061#ifdef WLAN_FEATURE_P2P
2062 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2063#endif
2064 )
2065 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302066 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002067
2068 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302069
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002070 if (old)
2071 return -EALREADY;
2072
2073 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2074
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302075 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002076 {
2077 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302078 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002079 return -EINVAL;
2080 }
2081 pAdapter->sessionCtx.ap.beacon = new;
2082 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2083 params->ssid_len, params->hidden_ssid);
2084 }
2085
2086 EXIT();
2087 return status;
2088}
2089
2090
2091static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2092 struct net_device *dev,
2093 struct cfg80211_beacon_data *params)
2094{
2095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2096 int status=VOS_STATUS_SUCCESS;
2097
2098 ENTER();
2099
2100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2101 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002102 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2103 {
2104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2105 return -EAGAIN;
2106 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002107
2108 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2109#ifdef WLAN_FEATURE_P2P
2110 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2111#endif
2112 )
2113 {
2114 beacon_data_t *old,*new;
2115
2116 old = pAdapter->sessionCtx.ap.beacon;
2117
2118 if (!old)
2119 return -ENOENT;
2120
2121 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2122
2123 if(status != VOS_STATUS_SUCCESS) {
2124 hddLog(VOS_TRACE_LEVEL_FATAL,
2125 "%s: Error!!! Allocating the new beacon\n",__func__);
2126 return -EINVAL;
2127 }
2128
2129 pAdapter->sessionCtx.ap.beacon = new;
2130
2131 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2132 }
2133
2134 EXIT();
2135 return status;
2136}
2137
2138#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2139
Jeff Johnson295189b2012-06-20 16:38:30 -07002140
2141static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2142 struct net_device *dev,
2143 struct bss_parameters *params)
2144{
2145 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2146
2147 ENTER();
2148
2149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2150 __func__,pAdapter->device_mode);
2151
2152 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2153#ifdef WLAN_FEATURE_P2P
2154 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2155#endif
2156 )
2157 {
2158 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2159 * want to update this parameter */
2160 if (-1 != params->ap_isolate)
2161 {
2162 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2163 }
2164 }
2165
2166 EXIT();
2167 return 0;
2168}
2169
2170/*
2171 * FUNCTION: wlan_hdd_cfg80211_change_iface
2172 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2173 */
2174int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2175 struct net_device *ndev,
2176 enum nl80211_iftype type,
2177 u32 *flags,
2178 struct vif_params *params
2179 )
2180{
2181 struct wireless_dev *wdev;
2182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2183 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002184 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002185 tCsrRoamProfile *pRoamProfile = NULL;
2186 eCsrRoamBssType LastBSSType;
2187 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2188 eMib_dot11DesiredBssType connectedBssType;
2189 VOS_STATUS status;
2190
2191 ENTER();
2192
2193 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2194 {
2195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2196 return -EAGAIN;
2197 }
2198
2199 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2200 __func__, pAdapter->device_mode);
2201
2202 wdev = ndev->ieee80211_ptr;
2203
2204#ifdef WLAN_BTAMP_FEATURE
2205 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2206 (NL80211_IFTYPE_ADHOC == type)||
2207 (NL80211_IFTYPE_AP == type)||
2208 (NL80211_IFTYPE_P2P_GO == type))
2209 {
2210 pHddCtx->isAmpAllowed = VOS_FALSE;
2211 // stop AMP traffic
2212 status = WLANBAP_StopAmp();
2213 if(VOS_STATUS_SUCCESS != status )
2214 {
2215 pHddCtx->isAmpAllowed = VOS_TRUE;
2216 hddLog(VOS_TRACE_LEVEL_FATAL,
2217 "%s: Failed to stop AMP", __func__);
2218 return -EINVAL;
2219 }
2220 }
2221#endif //WLAN_BTAMP_FEATURE
2222 /* Reset the current device mode bit mask*/
2223 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2224
2225 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2226#ifdef WLAN_FEATURE_P2P
2227 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002228 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002229#endif
2230 )
2231 {
2232 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2233 pRoamProfile = &pWextState->roamProfile;
2234 LastBSSType = pRoamProfile->BSSType;
2235
2236 switch (type)
2237 {
2238 case NL80211_IFTYPE_STATION:
2239#ifdef WLAN_FEATURE_P2P
2240 case NL80211_IFTYPE_P2P_CLIENT:
2241#endif
2242 hddLog(VOS_TRACE_LEVEL_INFO,
2243 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2244 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002245#ifdef WLAN_FEATURE_11AC
2246 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2247 {
2248 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2249 }
2250#endif
2251 pRoamProfile->phyMode =
2252 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 wdev->iftype = type;
2254#ifdef WLAN_FEATURE_P2P
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002255 if (!strcmp("p2p0",ndev->name))
2256 {
2257 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2258 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2259 }
2260 else
2261 {
2262 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002265#endif
2266 break;
2267 case NL80211_IFTYPE_ADHOC:
2268 hddLog(VOS_TRACE_LEVEL_INFO,
2269 "%s: setting interface Type to ADHOC", __func__);
2270 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2271 pRoamProfile->phyMode =
2272 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2273 wdev->iftype = type;
2274 break;
2275
2276 case NL80211_IFTYPE_AP:
2277#ifdef WLAN_FEATURE_P2P
2278 case NL80211_IFTYPE_P2P_GO:
2279#endif
2280 {
2281 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2282 "%s: setting interface Type to %s", __func__,
2283 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2284
Mohit Khanna0f232092012-09-11 14:46:08 -07002285 if (NL80211_IFTYPE_AP == type)
2286 {
2287 /* As Loading WLAN Driver one interface being created for p2p device
2288 * address. This will take one HW STA and the max number of clients
2289 * that can connect to softAP will be reduced by one. so while changing
2290 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2291 * interface as it is not required in SoftAP mode.
2292 */
2293
2294 // Get P2P Adapter
2295 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2296
2297 if (pP2pAdapter)
2298 {
2299 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2300 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2301 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2302 }
2303 }
2304
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 //De-init the adapter.
2306 hdd_stop_adapter( pHddCtx, pAdapter );
2307 hdd_deinit_adapter( pHddCtx, pAdapter );
2308 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2309#ifdef WLAN_SOFTAP_FEATURE
2310#ifdef WLAN_FEATURE_P2P
2311 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2312 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2313#else
2314 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2315#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002316
2317 //Disable BMPS and IMPS if enabled
2318 //before starting Go
2319 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2320 {
2321 if(VOS_STATUS_E_FAILURE ==
2322 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2323 {
2324 //Fail to Exit BMPS
2325 VOS_ASSERT(0);
2326 }
2327 }
2328
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002329 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2330 (pConfig->apRandomBssidEnabled))
2331 {
2332 /* To meet Android requirements create a randomized
2333 MAC address of the form 02:1A:11:Fx:xx:xx */
2334 get_random_bytes(&ndev->dev_addr[3], 3);
2335 ndev->dev_addr[0] = 0x02;
2336 ndev->dev_addr[1] = 0x1A;
2337 ndev->dev_addr[2] = 0x11;
2338 ndev->dev_addr[3] |= 0xF0;
2339 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2340 VOS_MAC_ADDR_SIZE);
2341 pr_info("wlan: Generated HotSpot BSSID "
2342 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2343 ndev->dev_addr[0],
2344 ndev->dev_addr[1],
2345 ndev->dev_addr[2],
2346 ndev->dev_addr[3],
2347 ndev->dev_addr[4],
2348 ndev->dev_addr[5]);
2349 }
2350
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 hdd_set_ap_ops( pAdapter->dev );
2352
2353 status = hdd_init_ap_mode(pAdapter);
2354 if(status != VOS_STATUS_SUCCESS)
2355 {
2356 hddLog(VOS_TRACE_LEVEL_FATAL,
2357 "%s: Error initializing the ap mode", __func__);
2358 return -EINVAL;
2359 }
2360 hdd_set_conparam(1);
2361
2362#endif
2363 /*interface type changed update in wiphy structure*/
2364 if(wdev)
2365 {
2366 wdev->iftype = type;
2367 pHddCtx->change_iface = type;
2368 }
2369 else
2370 {
2371 hddLog(VOS_TRACE_LEVEL_ERROR,
2372 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2373 return -EINVAL;
2374 }
2375 goto done;
2376 }
2377
2378 default:
2379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2380 __func__);
2381 return -EOPNOTSUPP;
2382 }
2383 }
2384 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2385#ifdef WLAN_FEATURE_P2P
2386 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2387#endif
2388 )
2389 {
2390 switch(type)
2391 {
2392 case NL80211_IFTYPE_STATION:
2393#ifdef WLAN_FEATURE_P2P
2394 case NL80211_IFTYPE_P2P_CLIENT:
2395#endif
2396 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002397 hdd_stop_adapter( pHddCtx, pAdapter );
2398 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002399 wdev->iftype = type;
2400#ifdef WLAN_FEATURE_P2P
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002401 if (!strcmp("p2p0",ndev->name))
2402 {
2403 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2404 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2405 }
2406 else
2407 {
2408 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002409 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002411#endif
2412 hdd_set_conparam(0);
2413 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2415 hdd_set_station_ops( pAdapter->dev );
2416 status = hdd_init_station_mode( pAdapter );
2417 if( VOS_STATUS_SUCCESS != status )
2418 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002419 /* In case of JB, for P2P-GO, only change interface will be called,
2420 * This is the right place to enable back bmps_imps()
2421 */
2422 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 goto done;
2424 case NL80211_IFTYPE_AP:
2425#ifdef WLAN_FEATURE_P2P
2426 case NL80211_IFTYPE_P2P_GO:
2427#endif
2428 wdev->iftype = type;
2429#ifdef WLAN_FEATURE_P2P
2430 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2431 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2432#endif
2433 goto done;
2434 default:
2435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2436 __func__);
2437 return -EOPNOTSUPP;
2438
2439 }
2440
2441 }
2442 else
2443 {
2444 return -EOPNOTSUPP;
2445 }
2446
2447
2448 if(pRoamProfile)
2449 {
2450 if ( LastBSSType != pRoamProfile->BSSType )
2451 {
2452 /*interface type changed update in wiphy structure*/
2453 wdev->iftype = type;
2454
2455 /*the BSS mode changed, We need to issue disconnect
2456 if connected or in IBSS disconnect state*/
2457 if ( hdd_connGetConnectedBssType(
2458 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2459 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2460 {
2461 /*need to issue a disconnect to CSR.*/
2462 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2463 if( eHAL_STATUS_SUCCESS ==
2464 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2465 pAdapter->sessionId,
2466 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2467 {
2468 wait_for_completion_interruptible_timeout(
2469 &pAdapter->disconnect_comp_var,
2470 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2471 }
2472 }
2473 }
2474 }
2475
2476done:
2477 /*set bitmask based on updated value*/
2478 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2479#ifdef WLAN_BTAMP_FEATURE
2480 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2481 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2482 {
2483 //we are ok to do AMP
2484 pHddCtx->isAmpAllowed = VOS_TRUE;
2485 }
2486#endif //WLAN_BTAMP_FEATURE
2487 EXIT();
2488 return 0;
2489}
2490
2491static int wlan_hdd_change_station(struct wiphy *wiphy,
2492 struct net_device *dev,
2493 u8 *mac,
2494 struct station_parameters *params)
2495{
2496 VOS_STATUS status = VOS_STATUS_SUCCESS;
2497 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2498 v_MACADDR_t STAMacAddress;
2499
Jeff Johnsone7245742012-09-05 17:12:55 -07002500 ENTER();
2501
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002502 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2503 {
2504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2505 "%s:LOGP in Progress. Ignore!!!", __func__);
2506 return -EAGAIN;
2507 }
2508
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2510
2511 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2512#ifdef WLAN_FEATURE_P2P
2513 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2514#endif
2515 )
2516 {
2517 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2518 {
2519 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2520 WLANTL_STA_AUTHENTICATED);
2521
2522 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002523 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002524 return -EINVAL;
2525 }
2526 }
2527
Jeff Johnsone7245742012-09-05 17:12:55 -07002528 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 return status;
2530}
2531
2532/*
2533 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2534 * This function is used to get peer station index in IBSS mode
2535 */
2536static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2537{
2538 u8 idx = 0;
2539 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2540 ENTER();
2541 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2542 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2543 {
2544 if ( (0 !=
2545 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2546 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2547 temp, VOS_MAC_ADDR_SIZE)
2548 )
2549 {
2550 return idx;
2551 }
2552 }
2553 return idx;
2554}
2555
2556
2557/*
2558 * FUNCTION: wlan_hdd_cfg80211_add_key
2559 * This function is used to initialize the key information
2560 */
2561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2562static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2563 struct net_device *ndev,
2564 u8 key_index, bool pairwise,
2565 const u8 *mac_addr,
2566 struct key_params *params
2567 )
2568#else
2569static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2570 struct net_device *ndev,
2571 u8 key_index, const u8 *mac_addr,
2572 struct key_params *params
2573 )
2574#endif
2575{
2576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2577 tCsrRoamSetKey setKey;
2578 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2579 int status = 0;
2580 v_U32_t roamId= 0xFF;
2581 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2582 hdd_hostapd_state_t *pHostapdState;
2583 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002584 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002585
2586 ENTER();
2587
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002588 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2589 {
2590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2591 "%s:LOGP in Progress. Ignore!!!", __func__);
2592 return -EAGAIN;
2593 }
2594
Jeff Johnson295189b2012-06-20 16:38:30 -07002595 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2596 __func__,pAdapter->device_mode);
2597
2598 if (CSR_MAX_NUM_KEY <= key_index)
2599 {
2600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2601 key_index);
2602
2603 return -EINVAL;
2604 }
2605
2606 hddLog(VOS_TRACE_LEVEL_INFO,
2607 "%s: called with key index = %d & key length %d",
2608 __func__, key_index, params->key_len);
2609
2610 /*extract key idx, key len and key*/
2611 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2612 setKey.keyId = key_index;
2613 setKey.keyLength = params->key_len;
2614 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2615
2616 switch (params->cipher)
2617 {
2618 case WLAN_CIPHER_SUITE_WEP40:
2619 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2620 break;
2621
2622 case WLAN_CIPHER_SUITE_WEP104:
2623 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2624 break;
2625
2626 case WLAN_CIPHER_SUITE_TKIP:
2627 {
2628 u8 *pKey = &setKey.Key[0];
2629 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2630
2631 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2632
2633 /*Supplicant sends the 32bytes key in this order
2634
2635 |--------------|----------|----------|
2636 | Tk1 |TX-MIC | RX Mic |
2637 |--------------|----------|----------|
2638 <---16bytes---><--8bytes--><--8bytes-->
2639
2640 */
2641 /*Sme expects the 32 bytes key to be in the below order
2642
2643 |--------------|----------|----------|
2644 | Tk1 |RX-MIC | TX Mic |
2645 |--------------|----------|----------|
2646 <---16bytes---><--8bytes--><--8bytes-->
2647 */
2648 /* Copy the Temporal Key 1 (TK1) */
2649 vos_mem_copy(pKey, params->key,16);
2650
2651 /*Copy the rx mic first*/
2652 vos_mem_copy(&pKey[16],&params->key[24],8);
2653
2654 /*Copy the tx mic */
2655 vos_mem_copy(&pKey[24],&params->key[16],8);
2656
2657
2658 break;
2659 }
2660
2661 case WLAN_CIPHER_SUITE_CCMP:
2662 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2663 break;
2664
2665#ifdef FEATURE_WLAN_WAPI
2666 case WLAN_CIPHER_SUITE_SMS4:
2667 {
2668 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2669 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2670 params->key, params->key_len);
2671 return 0;
2672 }
2673#endif
2674#ifdef FEATURE_WLAN_CCX
2675 case WLAN_CIPHER_SUITE_KRK:
2676 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2677 break;
2678#endif
2679 default:
2680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2681 __func__, params->cipher);
2682 return -EOPNOTSUPP;
2683 }
2684
2685 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2686 __func__, setKey.encType);
2687
2688
2689
2690 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2691#ifdef WLAN_FEATURE_P2P
2692 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2693#endif
2694 )
2695 {
2696
2697
2698 if (
2699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2700 (!pairwise)
2701#else
2702 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2703#endif
2704 )
2705 {
2706 /* set group key*/
2707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08002708 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002709 __func__, __LINE__);
2710 setKey.keyDirection = eSIR_RX_ONLY;
2711 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2712 }
2713 else
2714 {
2715 /* set pairwise key*/
2716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2717 "%s- %d: setting pairwise key",
2718 __func__, __LINE__);
2719 setKey.keyDirection = eSIR_TX_RX;
2720 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2721 }
2722
2723 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2724 if( pHostapdState->bssState == BSS_START )
2725 {
2726 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2727
2728 if ( status != eHAL_STATUS_SUCCESS )
2729 {
2730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2731 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2732 __LINE__, status );
2733 }
2734 }
2735
2736 /* Saving WEP keys */
2737 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2738 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2739 {
2740 //Save the wep key in ap context. Issue setkey after the BSS is started.
2741 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2742 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2743 }
2744 else
2745 {
2746 //Save the key in ap context. Issue setkey after the BSS is started.
2747 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2748 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2749 }
2750 }
2751 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2752#ifdef WLAN_FEATURE_P2P
2753 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2754#endif
2755 )
2756 {
2757 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2758 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2759
2760 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
2761
2762 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
2763 params->key, params->key_len);
2764
2765 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2766
2767 if (!( ( IW_AUTH_KEY_MGMT_802_1X
2768 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2769 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2770 )
2771 &&
2772 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2773 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2774 )
2775 )
2776 {
2777 /* in case of static WEP, macaddr/bssid is not coming from nl80211
2778 * interface, copy bssid for pairwise key and group macaddr for
2779 * group key initialization*/
2780
2781 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2782
2783 pWextState->roamProfile.negotiatedUCEncryptionType =
2784 pHddStaCtx->conn_info.ucEncryptionType =
2785 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
2786 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
2787 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
2788
2789
2790 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2791 "%s: Negotiated encryption type %d", __func__,
2792 pWextState->roamProfile.negotiatedUCEncryptionType);
2793
2794 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
2795 &pWextState->roamProfile, true);
2796 setKey.keyLength = 0;
2797 setKey.keyDirection = eSIR_TX_RX;
2798
2799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2800 if (pairwise)
2801 {
2802#endif
2803 if (mac_addr)
2804 {
2805 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2806 }
2807 else
2808 {
2809 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
2810 * and peerMacAddress in case of IBSS*/
2811 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
2812 {
2813 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
2814 if (HDD_MAX_NUM_IBSS_STA != staidx)
2815 {
2816 vos_mem_copy(setKey.peerMac,
2817 &pHddStaCtx->conn_info.peerMacAddress[staidx],
2818 WNI_CFG_BSSID_LEN);
2819
2820 }
2821 else
2822 {
2823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
2824 __func__);
2825 return -EOPNOTSUPP;
2826 }
2827 }
2828 else
2829 {
2830 vos_mem_copy(setKey.peerMac,
2831 &pHddStaCtx->conn_info.bssId[0],
2832 WNI_CFG_BSSID_LEN);
2833 }
2834 }
2835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2836 }
2837 else
2838 {
2839 /* set group key*/
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2841 "%s- %d: setting Group key",
2842 __func__, __LINE__);
2843 setKey.keyDirection = eSIR_RX_ONLY;
2844 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2845 }
2846#endif
2847 }
2848 else if (
2849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2850 (!pairwise)
2851#else
2852 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2853#endif
2854 )
2855 {
2856 /* set group key*/
2857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2858 "%s- %d: setting Group key",
2859 __func__, __LINE__);
2860 setKey.keyDirection = eSIR_RX_ONLY;
2861 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2862 }
2863 else
2864 {
2865 /* set pairwise key*/
2866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2867 "%s- %d: setting pairwise key",
2868 __func__, __LINE__);
2869 setKey.keyDirection = eSIR_TX_RX;
2870 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2871 }
2872
2873 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2874 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2875 __func__, setKey.peerMac[0], setKey.peerMac[1],
2876 setKey.peerMac[2], setKey.peerMac[3],
2877 setKey.peerMac[4], setKey.peerMac[5],
2878 setKey.keyDirection);
2879
2880 vos_status = wlan_hdd_check_ula_done(pAdapter);
2881
2882 if ( vos_status != VOS_STATUS_SUCCESS )
2883 {
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
2886 __LINE__, vos_status );
2887
2888 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2889
2890 return -EINVAL;
2891
2892 }
2893
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002894#ifdef WLAN_FEATURE_VOWIFI_11R
2895 /* The supplicant may attempt to set the PTK once pre-authentication is done.
2896 Save the key in the UMAC and include it in the ADD BSS request */
2897 /*TODO 11r - is this used?? */
2898 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
2899 if( halStatus == eHAL_STATUS_SUCCESS )
2900 {
2901 return halStatus;
2902 }
2903#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07002904
2905 /* issue set key request to SME*/
2906 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2907 pAdapter->sessionId, &setKey, &roamId );
2908
2909 if ( 0 != status )
2910 {
2911 hddLog(VOS_TRACE_LEVEL_ERROR,
2912 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
2913 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2914 return -EINVAL;
2915 }
2916
2917
2918 /* in case of IBSS as there was no information available about WEP keys during
2919 * IBSS join, group key intialized with NULL key, so re-initialize group key
2920 * with correct value*/
2921 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
2922 !( ( IW_AUTH_KEY_MGMT_802_1X
2923 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2924 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2925 )
2926 &&
2927 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2928 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2929 )
2930 )
2931 {
2932 setKey.keyDirection = eSIR_RX_ONLY;
2933 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2934
2935 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2936 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2937 __func__, setKey.peerMac[0], setKey.peerMac[1],
2938 setKey.peerMac[2], setKey.peerMac[3],
2939 setKey.peerMac[4], setKey.peerMac[5],
2940 setKey.keyDirection);
2941
2942 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2943 pAdapter->sessionId, &setKey, &roamId );
2944
2945 if ( 0 != status )
2946 {
2947 hddLog(VOS_TRACE_LEVEL_ERROR,
2948 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
2949 __func__, status);
2950 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2951 return -EINVAL;
2952 }
2953 }
2954 }
2955
2956 return 0;
2957}
2958
2959/*
2960 * FUNCTION: wlan_hdd_cfg80211_get_key
2961 * This function is used to get the key information
2962 */
2963#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2964static int wlan_hdd_cfg80211_get_key(
2965 struct wiphy *wiphy,
2966 struct net_device *ndev,
2967 u8 key_index, bool pairwise,
2968 const u8 *mac_addr, void *cookie,
2969 void (*callback)(void *cookie, struct key_params*)
2970 )
2971#else
2972static int wlan_hdd_cfg80211_get_key(
2973 struct wiphy *wiphy,
2974 struct net_device *ndev,
2975 u8 key_index, const u8 *mac_addr, void *cookie,
2976 void (*callback)(void *cookie, struct key_params*)
2977 )
2978#endif
2979{
2980 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2981 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2982 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2983 struct key_params params;
2984
2985 ENTER();
2986
2987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2988 __func__,pAdapter->device_mode);
2989
2990 memset(&params, 0, sizeof(params));
2991
2992 if (CSR_MAX_NUM_KEY <= key_index)
2993 {
2994 return -EINVAL;
2995 }
2996
2997 switch(pRoamProfile->EncryptionType.encryptionType[0])
2998 {
2999 case eCSR_ENCRYPT_TYPE_NONE:
3000 params.cipher = IW_AUTH_CIPHER_NONE;
3001 break;
3002
3003 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3004 case eCSR_ENCRYPT_TYPE_WEP40:
3005 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3006 break;
3007
3008 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3009 case eCSR_ENCRYPT_TYPE_WEP104:
3010 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3011 break;
3012
3013 case eCSR_ENCRYPT_TYPE_TKIP:
3014 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3015 break;
3016
3017 case eCSR_ENCRYPT_TYPE_AES:
3018 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3019 break;
3020
3021 default:
3022 params.cipher = IW_AUTH_CIPHER_NONE;
3023 break;
3024 }
3025
3026 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3027 params.seq_len = 0;
3028 params.seq = NULL;
3029 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3030 callback(cookie, &params);
3031 return 0;
3032}
3033
3034/*
3035 * FUNCTION: wlan_hdd_cfg80211_del_key
3036 * This function is used to delete the key information
3037 */
3038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3039static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3040 struct net_device *ndev,
3041 u8 key_index,
3042 bool pairwise,
3043 const u8 *mac_addr
3044 )
3045#else
3046static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3047 struct net_device *ndev,
3048 u8 key_index,
3049 const u8 *mac_addr
3050 )
3051#endif
3052{
3053 int status = 0;
3054
3055 //This code needs to be revisited. There is sme_removeKey API, we should
3056 //plan to use that. After the change to use correct index in setkey,
3057 //it is observed that this is invalidating peer
3058 //key index whenever re-key is done. This is affecting data link.
3059 //It should be ok to ignore del_key.
3060#if 0
3061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3062 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3063 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3064 tCsrRoamSetKey setKey;
3065 v_U32_t roamId= 0xFF;
3066
3067 ENTER();
3068
3069 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3070 __func__,pAdapter->device_mode);
3071
3072 if (CSR_MAX_NUM_KEY <= key_index)
3073 {
3074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3075 key_index);
3076
3077 return -EINVAL;
3078 }
3079
3080 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3081 setKey.keyId = key_index;
3082
3083 if (mac_addr)
3084 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3085 else
3086 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3087
3088 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3089
3090 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3091#ifdef WLAN_FEATURE_P2P
3092 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3093#endif
3094 )
3095 {
3096
3097 hdd_hostapd_state_t *pHostapdState =
3098 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3099 if( pHostapdState->bssState == BSS_START)
3100 {
3101 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3102
3103 if ( status != eHAL_STATUS_SUCCESS )
3104 {
3105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3106 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3107 __LINE__, status );
3108 }
3109 }
3110 }
3111 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3112#ifdef WLAN_FEATURE_P2P
3113 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3114#endif
3115 )
3116 {
3117 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3118
3119 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3120
3121 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3122 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3123 __func__, setKey.peerMac[0], setKey.peerMac[1],
3124 setKey.peerMac[2], setKey.peerMac[3],
3125 setKey.peerMac[4], setKey.peerMac[5]);
3126 if(pAdapter->sessionCtx.station.conn_info.connState ==
3127 eConnectionState_Associated)
3128 {
3129 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3130 pAdapter->sessionId, &setKey, &roamId );
3131
3132 if ( 0 != status )
3133 {
3134 hddLog(VOS_TRACE_LEVEL_ERROR,
3135 "%s: sme_RoamSetKey failure, returned %d",
3136 __func__, status);
3137 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3138 return -EINVAL;
3139 }
3140 }
3141 }
3142#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003143 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003144 return status;
3145}
3146
3147/*
3148 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3149 * This function is used to set the default tx key index
3150 */
3151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3152static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3153 struct net_device *ndev,
3154 u8 key_index,
3155 bool unicast, bool multicast)
3156#else
3157static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3158 struct net_device *ndev,
3159 u8 key_index)
3160#endif
3161{
3162 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3163 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3164 int status = 0;
3165 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3166
3167 ENTER();
3168
3169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3170 __func__,pAdapter->device_mode, key_index);
3171
3172 if (CSR_MAX_NUM_KEY <= key_index)
3173 {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3175 key_index);
3176
3177 return -EINVAL;
3178 }
3179
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003180 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3181 {
3182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3183 "%s:LOGP in Progress. Ignore!!!", __func__);
3184 return -EAGAIN;
3185 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3188#ifdef WLAN_FEATURE_P2P
3189 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3190#endif
3191 )
3192 {
3193 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3194 (eCSR_ENCRYPT_TYPE_TKIP !=
3195 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3196 (eCSR_ENCRYPT_TYPE_AES !=
3197 pWextState->roamProfile.EncryptionType.encryptionType[0])
3198 )
3199 {
3200 /* if default key index is not same as previous one,
3201 * then update the default key index */
3202
3203 tCsrRoamSetKey setKey;
3204 v_U32_t roamId= 0xFF;
3205 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3206
3207 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3208 __func__, key_index);
3209
3210 Keys->defaultIndex = (u8)key_index;
3211 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3212 setKey.keyId = key_index;
3213 setKey.keyLength = Keys->KeyLength[key_index];
3214
3215 vos_mem_copy(&setKey.Key[0],
3216 &Keys->KeyMaterial[key_index][0],
3217 Keys->KeyLength[key_index]);
3218
3219 setKey.keyDirection = eSIR_TX_ONLY;
3220
3221 vos_mem_copy(setKey.peerMac,
3222 &pHddStaCtx->conn_info.bssId[0],
3223 WNI_CFG_BSSID_LEN);
3224
3225 setKey.encType =
3226 pWextState->roamProfile.EncryptionType.encryptionType[0];
3227
3228 /* issue set key request */
3229 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3230 pAdapter->sessionId, &setKey, &roamId );
3231
3232 if ( 0 != status )
3233 {
3234 hddLog(VOS_TRACE_LEVEL_ERROR,
3235 "%s: sme_RoamSetKey failed, returned %d", __func__,
3236 status);
3237 return -EINVAL;
3238 }
3239 }
3240 }
3241
3242 /* In SoftAp mode setting key direction for default mode */
3243 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3244 {
3245 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3246 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3247 (eCSR_ENCRYPT_TYPE_AES !=
3248 pWextState->roamProfile.EncryptionType.encryptionType[0])
3249 )
3250 {
3251 /* Saving key direction for default key index to TX default */
3252 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3253 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3254 }
3255 }
3256
3257 return status;
3258}
3259
3260/**
3261 * FUNCTION: wlan_hdd_cfg80211_set_channel
3262 * This function is used to set the channel number
3263 */
3264int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
3265 struct ieee80211_channel *chan,
3266 enum nl80211_channel_type channel_type
3267 )
3268{
3269 v_U32_t num_ch = 0;
3270 u32 channel = 0;
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003271 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003272 int freq = chan->center_freq; /* freq is in MHZ */
3273
3274 ENTER();
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003275
3276 if( NULL == dev )
3277 {
3278 hddLog(VOS_TRACE_LEVEL_ERROR,
3279 "%s: Called with dev = NULL.\n", __func__);
3280 return -ENODEV;
3281 }
3282 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003283
3284 hddLog(VOS_TRACE_LEVEL_INFO,
3285 "%s: device_mode = %d freq = %d \n",__func__,
3286 pAdapter->device_mode, chan->center_freq);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07003287 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3288 {
3289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3290 return -EAGAIN;
3291 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003292
3293 /*
3294 * Do freq to chan conversion
3295 * TODO: for 11a
3296 */
3297
3298 channel = ieee80211_frequency_to_channel(freq);
3299
3300 /* Check freq range */
3301 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3302 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
3303 {
3304 hddLog(VOS_TRACE_LEVEL_ERROR,
3305 "%s: Channel [%d] is outside valid range from %d to %d\n",
3306 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3307 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3308 return -EINVAL;
3309 }
3310
3311 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3312
3313 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
3314#ifdef WLAN_FEATURE_P2P
3315 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
3316#endif
3317 )
3318 {
3319 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
3320 {
3321 hddLog(VOS_TRACE_LEVEL_ERROR,
3322 "%s: Invalid Channel [%d] \n", __func__, channel);
3323 return -EINVAL;
3324 }
3325 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3326 "%s: set channel to [%d] for device mode =%d",
3327 __func__, channel,pAdapter->device_mode);
3328 }
3329 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3330#ifdef WLAN_FEATURE_P2P
3331 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3332#endif
3333 )
3334 {
3335 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3336 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
3337 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3338
3339 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
3340 {
3341 /* Link is up then return cant set channel*/
3342 hddLog( VOS_TRACE_LEVEL_ERROR,
3343 "%s: IBSS Associated, can't set the channel\n", __func__);
3344 return -EINVAL;
3345 }
3346
3347 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
3348 pHddStaCtx->conn_info.operationChannel = channel;
3349 pRoamProfile->ChannelInfo.ChannelList =
3350 &pHddStaCtx->conn_info.operationChannel;
3351 }
3352 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3353#ifdef WLAN_FEATURE_P2P
3354 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3355#endif
3356 )
3357 {
3358 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
3359
3360 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3361 {
3362 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3363
3364 /* If auto channel selection is configured as enable/ 1 then ignore
3365 channel set by supplicant
3366 */
3367 if ( cfg_param->apAutoChannelSelection )
3368 {
3369 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
3370
3371 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3372 "%s: set channel to auto channel (0) for device mode =%d",
3373 __func__, pAdapter->device_mode);
3374 }
3375 }
3376 }
3377 else
3378 {
3379 hddLog(VOS_TRACE_LEVEL_FATAL,
3380 "%s: Invalid device mode failed to set valid channel", __func__);
3381 return -EINVAL;
3382 }
3383 EXIT();
3384 return 0;
3385}
3386
3387
3388
3389/*
3390 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3391 * This function is used to inform the BSS details to nl80211 interface.
3392 */
3393static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3394 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3395{
3396 struct net_device *dev = pAdapter->dev;
3397 struct wireless_dev *wdev = dev->ieee80211_ptr;
3398 struct wiphy *wiphy = wdev->wiphy;
3399 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3400 int chan_no;
3401 int ie_length;
3402 const char *ie;
3403 unsigned int freq;
3404 struct ieee80211_channel *chan;
3405 int rssi = 0;
3406 struct cfg80211_bss *bss = NULL;
3407
3408 ENTER();
3409
3410 if( NULL == pBssDesc )
3411 {
3412 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3413 return bss;
3414 }
3415
3416 chan_no = pBssDesc->channelId;
3417 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3418 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3419
3420 if( NULL == ie )
3421 {
3422 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3423 return bss;
3424 }
3425
3426#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3427 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3428 {
3429 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3430 }
3431 else
3432 {
3433 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3434 }
3435#else
3436 freq = ieee80211_channel_to_frequency(chan_no);
3437#endif
3438
3439 chan = __ieee80211_get_channel(wiphy, freq);
3440
3441 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3442 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3443 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3444 if (bss == NULL)
3445 {
3446 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3447
3448 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3449 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3450 pBssDesc->capabilityInfo,
3451 pBssDesc->beaconInterval, ie, ie_length,
3452 rssi, GFP_KERNEL ));
3453}
3454 else
3455 {
3456 return bss;
3457 }
3458}
3459
3460
3461
3462/*
3463 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3464 * This function is used to inform the BSS details to nl80211 interface.
3465 */
3466struct cfg80211_bss*
3467wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3468 tSirBssDescription *bss_desc
3469 )
3470{
3471 /*
3472 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3473 already exists in bss data base of cfg80211 for that particular BSS ID.
3474 Using cfg80211_inform_bss_frame to update the bss entry instead of
3475 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3476 now there is no possibility to get the mgmt(probe response) frame from PE,
3477 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3478 cfg80211_inform_bss_frame.
3479 */
3480 struct net_device *dev = pAdapter->dev;
3481 struct wireless_dev *wdev = dev->ieee80211_ptr;
3482 struct wiphy *wiphy = wdev->wiphy;
3483 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003484#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3485 qcom_ie_age *qie_age = NULL;
3486 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3487#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003488 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003489#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003490 const char *ie =
3491 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3492 unsigned int freq;
3493 struct ieee80211_channel *chan;
3494 struct ieee80211_mgmt *mgmt =
3495 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3496 struct cfg80211_bss *bss_status = NULL;
3497 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3498 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003499#ifdef WLAN_OPEN_SOURCE
3500 struct timespec ts;
3501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003502
3503 ENTER();
3504
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003505 if (!mgmt)
3506 return NULL;
3507
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003509
3510#ifdef WLAN_OPEN_SOURCE
3511 /* Android does not want the timestamp from the frame.
3512 Instead it wants a monotonic increasing value */
3513 get_monotonic_boottime(&ts);
3514 mgmt->u.probe_resp.timestamp =
3515 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3516#else
3517 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003518 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3519 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003520
3521#endif
3522
Jeff Johnson295189b2012-06-20 16:38:30 -07003523 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3524 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003525
3526#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3527 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3528 /* Assuming this is the last IE, copy at the end */
3529 ie_length -=sizeof(qcom_ie_age);
3530 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3531 qie_age->element_id = QCOM_VENDOR_IE_ID;
3532 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3533 qie_age->oui_1 = QCOM_OUI1;
3534 qie_age->oui_2 = QCOM_OUI2;
3535 qie_age->oui_3 = QCOM_OUI3;
3536 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3537 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3538#endif
3539
Jeff Johnson295189b2012-06-20 16:38:30 -07003540 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3541
3542 mgmt->frame_control |=
3543 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3544
3545#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3546 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3547 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3548 {
3549 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3550 }
3551 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3552 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3553
3554 {
3555 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3556 }
3557 else
3558 {
3559 kfree(mgmt);
3560 return NULL;
3561 }
3562#else
3563 freq = ieee80211_channel_to_frequency(chan_no);
3564#endif
3565 chan = __ieee80211_get_channel(wiphy, freq);
3566
3567 /*To keep the rssi icon of the connected AP in the scan window
3568 *and the rssi icon of the wireless networks in sync
3569 * */
3570 if (( eConnectionState_Associated ==
3571 pAdapter->sessionCtx.station.conn_info.connState ) &&
3572 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3573 pAdapter->sessionCtx.station.conn_info.bssId,
3574 WNI_CFG_BSSID_LEN)))
3575 {
3576 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3577 rssi = (pAdapter->rssi * 100);
3578 }
3579 else
3580 {
3581 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3582 }
3583
3584 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3585 frame_len, rssi, GFP_KERNEL);
3586 kfree(mgmt);
3587 return bss_status;
3588}
3589
3590/*
3591 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3592 * This function is used to update the BSS data base of CFG8011
3593 */
3594struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3595 tCsrRoamInfo *pRoamInfo
3596 )
3597{
3598 tCsrRoamConnectedProfile roamProfile;
3599 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3600 struct cfg80211_bss *bss = NULL;
3601
3602 ENTER();
3603
3604 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3605 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3606
3607 if (NULL != roamProfile.pBssDesc)
3608 {
3609 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3610 &roamProfile);
3611
3612 if (NULL == bss)
3613 {
3614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3615 __func__);
3616 }
3617
3618 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3619 }
3620 else
3621 {
3622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3623 __func__);
3624 }
3625 return bss;
3626}
3627
3628/*
3629 * FUNCTION: wlan_hdd_cfg80211_update_bss
3630 */
3631static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3632 hdd_adapter_t *pAdapter
3633 )
3634{
3635 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3636 tCsrScanResultInfo *pScanResult;
3637 eHalStatus status = 0;
3638 tScanResultHandle pResult;
3639 struct cfg80211_bss *bss_status = NULL;
3640
3641 ENTER();
3642
3643 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3644 {
3645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3646 return -EAGAIN;
3647 }
3648
3649 /*
3650 * start getting scan results and populate cgf80211 BSS database
3651 */
3652 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3653
3654 /* no scan results */
3655 if (NULL == pResult)
3656 {
3657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3658 return status;
3659 }
3660
3661 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3662
3663 while (pScanResult)
3664 {
3665 /*
3666 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3667 * entry already exists in bss data base of cfg80211 for that
3668 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3669 * bss entry instead of cfg80211_inform_bss, But this call expects
3670 * mgmt packet as input. As of now there is no possibility to get
3671 * the mgmt(probe response) frame from PE, converting bss_desc to
3672 * ieee80211_mgmt(probe response) and passing to c
3673 * fg80211_inform_bss_frame.
3674 * */
3675
3676 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3677 &pScanResult->BssDescriptor);
3678
3679
3680 if (NULL == bss_status)
3681 {
3682 hddLog(VOS_TRACE_LEVEL_INFO,
3683 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3684 }
3685 else
3686 {
3687 cfg80211_put_bss(bss_status);
3688 }
3689
3690 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3691 }
3692
3693 sme_ScanResultPurge(hHal, pResult);
3694
3695 return 0;
3696}
3697
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003698void
3699hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3700{
3701 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003702 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3703 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3704 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003705} /****** end hddPrintMacAddr() ******/
3706
3707void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003708hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003709{
3710 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003711 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3712 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3713 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3714 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003715} /****** end hddPrintPmkId() ******/
3716
3717//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3718//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3719
3720//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3721//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3722
3723#define dump_bssid(bssid) \
3724 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003725 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3726 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3727 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003728 }
3729
3730#define dump_pmkid(pMac, pmkid) \
3731 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003732 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3733 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3734 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003735 }
3736
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003737#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003738/*
3739 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3740 * This function is used to notify the supplicant of a new PMKSA candidate.
3741 */
3742int wlan_hdd_cfg80211_pmksa_candidate_notify(
3743 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3744 int index, bool preauth )
3745{
Jeff Johnsone7245742012-09-05 17:12:55 -07003746#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003747 struct net_device *dev = pAdapter->dev;
3748
3749 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003750 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003751
3752 if( NULL == pRoamInfo )
3753 {
3754 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3755 return -EINVAL;
3756 }
3757
3758 dump_bssid(pRoamInfo->bssid);
3759 cfg80211_pmksa_candidate_notify(dev, index,
3760 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003761#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003762 return 0;
3763}
3764#endif //FEATURE_WLAN_LFR
3765
Jeff Johnson295189b2012-06-20 16:38:30 -07003766/*
3767 * FUNCTION: hdd_cfg80211_scan_done_callback
3768 * scanning callback function, called after finishing scan
3769 *
3770 */
3771static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3772 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3773{
3774 struct net_device *dev = (struct net_device *) pContext;
3775 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003777 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3778 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003779 struct cfg80211_scan_request *req = NULL;
3780 int ret = 0;
3781
3782 ENTER();
3783
3784 hddLog(VOS_TRACE_LEVEL_INFO,
3785 "%s called with halHandle = %p, pContext = %p,"
3786 "scanID = %d, returned status = %d\n",
3787 __func__, halHandle, pContext, (int) scanId, (int) status);
3788
3789 //Block on scan req completion variable. Can't wait forever though.
3790 ret = wait_for_completion_interruptible_timeout(
3791 &pScanInfo->scan_req_completion_event,
3792 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3793 if (!ret)
3794 {
3795 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003796 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003797 }
3798
3799 if(pScanInfo->mScanPending != VOS_TRUE)
3800 {
3801 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003802 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003803 }
3804
3805 /* Check the scanId */
3806 if (pScanInfo->scanId != scanId)
3807 {
3808 hddLog(VOS_TRACE_LEVEL_INFO,
3809 "%s called with mismatched scanId pScanInfo->scanId = %d "
3810 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3811 (int) scanId);
3812 }
3813
Jeff Johnson295189b2012-06-20 16:38:30 -07003814 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3815 pAdapter);
3816
3817 if (0 > ret)
3818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3819
3820
3821 /* If any client wait scan result through WEXT
3822 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003823 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003824 {
3825 /* The other scan request waiting for current scan finish
3826 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003827 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003828 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003829 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003830 }
3831 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003832 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003833 {
3834 struct net_device *dev = pAdapter->dev;
3835 union iwreq_data wrqu;
3836 int we_event;
3837 char *msg;
3838
3839 memset(&wrqu, '\0', sizeof(wrqu));
3840 we_event = SIOCGIWSCAN;
3841 msg = NULL;
3842 wireless_send_event(dev, we_event, &wrqu, msg);
3843 }
3844 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003845 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003846
3847 /* Get the Scan Req */
3848 req = pAdapter->request;
3849
3850 if (!req)
3851 {
3852 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003853 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003854 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 }
3856
3857 /*
3858 * setting up 0, just in case.
3859 */
3860 req->n_ssids = 0;
3861 req->n_channels = 0;
3862 req->ie = 0;
3863
Jeff Johnson295189b2012-06-20 16:38:30 -07003864 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07003865 /* Scan is no longer pending */
3866 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003867
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07003868 /*
3869 * cfg80211_scan_done informing NL80211 about completion
3870 * of scanning
3871 */
3872 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08003873 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07003874
Jeff Johnsone7245742012-09-05 17:12:55 -07003875allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003876 /* release the wake lock at the end of the scan*/
3877 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003878
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07003879 /* Acquire wakelock to handle the case where APP's tries to suspend
3880 * immediatly after the driver gets connect request(i.e after scan)
3881 * from supplicant, this result in app's is suspending and not able
3882 * to process the connect request to AP */
3883 hdd_allow_suspend_timeout(100);
3884
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 EXIT();
3886 return 0;
3887}
3888
3889/*
3890 * FUNCTION: wlan_hdd_cfg80211_scan
3891 * this scan respond to scan trigger and update cfg80211 scan database
3892 * later, scan dump command can be used to recieve scan results
3893 */
3894int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, struct net_device *dev,
3895 struct cfg80211_scan_request *request)
3896{
3897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3898 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3899 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3900 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3901 tCsrScanRequest scanRequest;
3902 tANI_U8 *channelList = NULL, i;
3903 v_U32_t scanId = 0;
3904 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003905 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003906#ifdef WLAN_FEATURE_P2P
3907 v_U8_t* pP2pIe = NULL;
3908#endif
3909
3910 ENTER();
3911
3912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3913 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003914
3915 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
3916 (eConnectionState_Connecting ==
3917 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
3918 {
3919 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08003920 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
3921 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003922 return -EBUSY;
3923 }
3924
Jeff Johnson295189b2012-06-20 16:38:30 -07003925#ifdef WLAN_BTAMP_FEATURE
3926 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003927 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003929 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 "%s: No scanning when AMP is on", __func__);
3931 return -EOPNOTSUPP;
3932 }
3933#endif
3934 //Scan on any other interface is not supported.
3935 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
3936 {
3937 hddLog(VOS_TRACE_LEVEL_ERROR,
3938 "%s: Not scanning on device_mode = %d",
3939 __func__, pAdapter->device_mode);
3940 return -EOPNOTSUPP;
3941 }
3942
3943 if (TRUE == pScanInfo->mScanPending)
3944 {
3945 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
3946 return -EBUSY;
3947 }
3948
3949 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3950 {
3951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3952 "%s:LOGP in Progress. Ignore!!!", __func__);
3953 return -EAGAIN;
3954 }
3955
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07003956 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
3957 {
3958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3959 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
3960 return -EAGAIN;
3961 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07003962 //Don't Allow Scan and return busy if Remain On
3963 //Channel and action frame is pending
3964 //Otherwise Cancel Remain On Channel and allow Scan
3965 //If no action frame pending
3966 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
3967 {
3968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
3969 return -EBUSY;
3970 }
3971
Jeff Johnson295189b2012-06-20 16:38:30 -07003972 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
3973 {
3974 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08003975 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003976 return -EAGAIN;
3977 }
3978 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
3979 {
3980 hddLog(VOS_TRACE_LEVEL_WARN,
3981 "%s: MAX TM Level Scan not allowed", __func__);
3982 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3983 return -EBUSY;
3984 }
3985 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3986
3987 vos_mem_zero( &scanRequest, sizeof(scanRequest));
3988
3989 if (NULL != request)
3990 {
3991 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
3992 (int)request->n_ssids);
3993
3994 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
3995 * Becasue of this, driver is assuming that this is not wildcard scan and so
3996 * is not aging out the scan results.
3997 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07003998 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07003999 {
4000 request->n_ssids = 0;
4001 }
4002
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004003 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004004 {
4005 tCsrSSIDInfo *SsidInfo;
4006 int j;
4007 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4008 /* Allocate num_ssid tCsrSSIDInfo structure */
4009 SsidInfo = scanRequest.SSIDs.SSIDList =
4010 ( tCsrSSIDInfo *)vos_mem_malloc(
4011 request->n_ssids*sizeof(tCsrSSIDInfo));
4012
4013 if(NULL == scanRequest.SSIDs.SSIDList)
4014 {
4015 hddLog(VOS_TRACE_LEVEL_ERROR,
4016 "memory alloc failed SSIDInfo buffer");
4017 return -ENOMEM;
4018 }
4019
4020 /* copy all the ssid's and their length */
4021 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4022 {
4023 /* get the ssid length */
4024 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4025 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4026 SsidInfo->SSID.length);
4027 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4028 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4029 j, SsidInfo->SSID.ssId);
4030 }
4031 /* set the scan type to active */
4032 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4033 }
4034 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4035 {
4036 /* set the scan type to active */
4037 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4038 }
4039 else
4040 {
4041 /*Set the scan type to default type, in this case it is ACTIVE*/
4042 scanRequest.scanType = pScanInfo->scan_mode;
4043 }
4044 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4045 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4046 }
4047 else
4048 {
4049 /* set the scan type to active */
4050 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4051 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4052
4053 /* set min and max channel time to zero */
4054 scanRequest.minChnTime = 0;
4055 scanRequest.maxChnTime = 0;
4056 }
4057
4058 /* set BSSType to default type */
4059 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4060
4061 /*TODO: scan the requested channels only*/
4062
4063 /*Right now scanning all the channels */
4064 if( request )
4065 {
4066 if( request->n_channels )
4067 {
4068 channelList = vos_mem_malloc( request->n_channels );
4069 if( NULL == channelList )
4070 {
4071 status = -ENOMEM;
4072 goto free_mem;
4073 }
4074
4075 for( i = 0 ; i < request->n_channels ; i++ )
4076 channelList[i] = request->channels[i]->hw_value;
4077 }
4078
4079 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4080 scanRequest.ChannelInfo.ChannelList = channelList;
4081
4082 /* set requestType to full scan */
4083 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004084
4085 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4086 * search (Flush on both full scan and social scan but not on single
4087 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4088 */
4089
4090 /* Supplicant does single channel scan after 8-way handshake
4091 * and in that case driver shoudnt flush scan results. If
4092 * driver flushes the scan results here and unfortunately if
4093 * the AP doesnt respond to our probe req then association
4094 * fails which is not desired
4095 */
4096
4097 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4098 {
4099 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4100 pAdapter->sessionId );
4101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004102
4103 if( request->ie_len )
4104 {
4105 /* save this for future association (join requires this) */
4106 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4107 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4108 pScanInfo->scanAddIE.length = request->ie_len;
4109
4110 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004111 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4112 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004113 )
4114 {
4115 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4116 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4117 }
4118
4119 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4120 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4121
4122#ifdef WLAN_FEATURE_P2P
4123 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4124 request->ie_len);
4125 if (pP2pIe != NULL)
4126 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004127#ifdef WLAN_FEATURE_P2P_DEBUG
4128 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4129 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4130 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4131 {
4132 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4133 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4134 "Go nego completed to Connection is started");
4135 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4136 "for 8way Handshake");
4137 }
4138 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4139 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4140 {
4141 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4142 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4143 "Disconnected state to Connection is started");
4144 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4145 "for 4way Handshake");
4146 }
4147#endif
4148
Jeff Johnsone7245742012-09-05 17:12:55 -07004149 /* no_cck will be set during p2p find to disable 11b rates */
4150 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004151 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 hddLog(VOS_TRACE_LEVEL_INFO,
4153 "%s: This is a P2P Search", __func__);
4154 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004155
Jeff Johnsone7245742012-09-05 17:12:55 -07004156 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4157 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004158 /* set requestType to P2P Discovery */
4159 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004160 }
4161
4162 /*
4163 Skip Dfs Channel in case of P2P Search
4164 if it is set in ini file
4165 */
4166 if(cfg_param->skipDfsChnlInP2pSearch)
4167 {
4168 scanRequest.skipDfsChnlInP2pSearch = 1;
4169 }
4170 else
4171 {
4172 scanRequest.skipDfsChnlInP2pSearch = 0;
4173 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004174
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 }
4176 }
4177#endif
4178 }
4179 }
4180
4181 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4182
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004183 /* acquire the wakelock to avoid the apps suspend during the scan. To
4184 * address the following issues.
4185 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4186 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4187 * for long time, this result in apps running at full power for long time.
4188 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4189 * be stuck in full power because of resume BMPS
4190 */
4191 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004192
4193 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004194 pAdapter->sessionId, &scanRequest, &scanId,
4195 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004196
Jeff Johnson295189b2012-06-20 16:38:30 -07004197 if (eHAL_STATUS_SUCCESS != status)
4198 {
4199 hddLog(VOS_TRACE_LEVEL_ERROR,
4200 "%s: sme_ScanRequest returned error %d", __func__, status);
4201 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004202 if(eHAL_STATUS_RESOURCES == status)
4203 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004204 hddLog(VOS_TRACE_LEVEL_INFO, "%s: HO is in progress.So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004205 status = -EBUSY;
4206 } else {
4207 status = -EIO;
4208 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004209 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 goto free_mem;
4211 }
4212
4213 pScanInfo->mScanPending = TRUE;
4214 pAdapter->request = request;
4215 pScanInfo->scanId = scanId;
4216
4217 complete(&pScanInfo->scan_req_completion_event);
4218
4219free_mem:
4220 if( scanRequest.SSIDs.SSIDList )
4221 {
4222 vos_mem_free(scanRequest.SSIDs.SSIDList);
4223 }
4224
4225 if( channelList )
4226 vos_mem_free( channelList );
4227
4228 EXIT();
4229
4230 return status;
4231}
4232
4233/*
4234 * FUNCTION: wlan_hdd_cfg80211_connect_start
4235 * This function is used to start the association process
4236 */
4237int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004238 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004239{
4240 int status = 0;
4241 hdd_wext_state_t *pWextState;
4242 v_U32_t roamId;
4243 tCsrRoamProfile *pRoamProfile;
4244 eMib_dot11DesiredBssType connectedBssType;
4245 eCsrAuthType RSNAuthType;
4246
4247 ENTER();
4248
4249 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4250
4251 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4252 {
4253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4254 return -EINVAL;
4255 }
4256
4257 pRoamProfile = &pWextState->roamProfile;
4258
4259 if (pRoamProfile)
4260 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004261 int ret = 0;
4262 hdd_station_ctx_t *pHddStaCtx;
4263 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4264 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4265
4266 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4267 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4268 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004269 {
4270 /* Issue disconnect to CSR */
4271 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4272 if( eHAL_STATUS_SUCCESS ==
4273 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4274 pAdapter->sessionId,
4275 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4276 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004277 ret = wait_for_completion_interruptible_timeout(
4278 &pAdapter->disconnect_comp_var,
4279 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4280 if (0 == ret)
4281 {
4282 VOS_ASSERT(0);
4283 }
4284 }
4285 }
4286 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4287 {
4288 ret = wait_for_completion_interruptible_timeout(
4289 &pAdapter->disconnect_comp_var,
4290 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4291 if (0 == ret)
4292 {
4293 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004294 }
4295 }
4296
4297 if (HDD_WMM_USER_MODE_NO_QOS ==
4298 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4299 {
4300 /*QoS not enabled in cfg file*/
4301 pRoamProfile->uapsd_mask = 0;
4302 }
4303 else
4304 {
4305 /*QoS enabled, update uapsd mask from cfg file*/
4306 pRoamProfile->uapsd_mask =
4307 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4308 }
4309
4310 pRoamProfile->SSIDs.numOfSSIDs = 1;
4311 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4312 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4313 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4314 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4315 ssid, ssid_len);
4316
4317 if (bssid)
4318 {
4319 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4320 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4321 WNI_CFG_BSSID_LEN);
4322 /* Save BSSID in seperate variable as well, as RoamProfile
4323 BSSID is getting zeroed out in the association process. And in
4324 case of join failure we should send valid BSSID to supplicant
4325 */
4326 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4327 WNI_CFG_BSSID_LEN);
4328 }
4329
4330 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4331 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4332 {
4333 /*set gen ie*/
4334 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4335 /*set auth*/
4336 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4337 }
4338 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4339 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4340 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4341 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4342 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4343 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4344 )
4345 {
4346 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4347 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4348 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4349 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4350 eCSR_AUTH_TYPE_AUTOSWITCH;
4351 pWextState->roamProfile.AuthType.authType[0] =
4352 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4353 }
4354#ifdef FEATURE_WLAN_WAPI
4355 if (pAdapter->wapi_info.nWapiMode)
4356 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004357 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004358 switch (pAdapter->wapi_info.wapiAuthMode)
4359 {
4360 case WAPI_AUTH_MODE_PSK:
4361 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004362 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 pAdapter->wapi_info.wapiAuthMode);
4364 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4365 break;
4366 }
4367 case WAPI_AUTH_MODE_CERT:
4368 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004369 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004370 pAdapter->wapi_info.wapiAuthMode);
4371 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4372 break;
4373 }
4374 } // End of switch
4375 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4376 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4377 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004378 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 pRoamProfile->AuthType.numEntries = 1;
4380 pRoamProfile->EncryptionType.numEntries = 1;
4381 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4382 pRoamProfile->mcEncryptionType.numEntries = 1;
4383 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4384 }
4385 }
4386#endif /* FEATURE_WLAN_WAPI */
4387 pRoamProfile->csrPersona = pAdapter->device_mode;
4388
Jeff Johnson32d95a32012-09-10 13:15:23 -07004389 if( operatingChannel )
4390 {
4391 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4392 pRoamProfile->ChannelInfo.numOfChannels = 1;
4393 }
4394
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004395 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4396 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4397 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4398 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004399 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4400 */
4401 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4402 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4403 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004404
Jeff Johnson295189b2012-06-20 16:38:30 -07004405 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4406 pAdapter->sessionId, pRoamProfile, &roamId);
4407
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004408 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304409 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4410
4411 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004412 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4413 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4414 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304415 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004416 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304417 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004418
4419 pRoamProfile->ChannelInfo.ChannelList = NULL;
4420 pRoamProfile->ChannelInfo.numOfChannels = 0;
4421
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 }
4423 else
4424 {
4425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4426 return -EINVAL;
4427 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004428 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004429 return status;
4430}
4431
4432/*
4433 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4434 * This function is used to set the authentication type (OPEN/SHARED).
4435 *
4436 */
4437static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4438 enum nl80211_auth_type auth_type)
4439{
4440 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4441 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4442
4443 ENTER();
4444
4445 /*set authentication type*/
4446 switch (auth_type)
4447 {
4448 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4449 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004450#ifdef WLAN_FEATURE_VOWIFI_11R
4451 case NL80211_AUTHTYPE_FT:
4452#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 hddLog(VOS_TRACE_LEVEL_INFO,
4454 "%s: set authentication type to OPEN", __func__);
4455 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4456 break;
4457
4458 case NL80211_AUTHTYPE_SHARED_KEY:
4459 hddLog(VOS_TRACE_LEVEL_INFO,
4460 "%s: set authentication type to SHARED", __func__);
4461 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4462 break;
4463#ifdef FEATURE_WLAN_CCX
4464 case NL80211_AUTHTYPE_NETWORK_EAP:
4465 hddLog(VOS_TRACE_LEVEL_INFO,
4466 "%s: set authentication type to CCKM WPA", __func__);
4467 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4468 break;
4469#endif
4470
4471
4472 default:
4473 hddLog(VOS_TRACE_LEVEL_ERROR,
4474 "%s: Unsupported authentication type %d", __func__,
4475 auth_type);
4476 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4477 return -EINVAL;
4478 }
4479
4480 pWextState->roamProfile.AuthType.authType[0] =
4481 pHddStaCtx->conn_info.authType;
4482 return 0;
4483}
4484
4485/*
4486 * FUNCTION: wlan_hdd_set_akm_suite
4487 * This function is used to set the key mgmt type(PSK/8021x).
4488 *
4489 */
4490static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4491 u32 key_mgmt
4492 )
4493{
4494 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4495 ENTER();
4496
4497 /*set key mgmt type*/
4498 switch(key_mgmt)
4499 {
4500 case WLAN_AKM_SUITE_PSK:
4501 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4502 __func__);
4503 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4504 break;
4505
4506 case WLAN_AKM_SUITE_8021X:
4507 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4508 __func__);
4509 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4510 break;
4511#ifdef FEATURE_WLAN_CCX
4512#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4513#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4514 case WLAN_AKM_SUITE_CCKM:
4515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4516 __func__);
4517 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4518 break;
4519#endif
4520
4521 default:
4522 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4523 __func__, key_mgmt);
4524 return -EINVAL;
4525
4526 }
4527 return 0;
4528}
4529
4530/*
4531 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4532 * This function is used to set the encryption type
4533 * (NONE/WEP40/WEP104/TKIP/CCMP).
4534 */
4535static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4536 u32 cipher,
4537 bool ucast
4538 )
4539{
4540 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4541 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4542 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4543
4544 ENTER();
4545
4546 if (!cipher)
4547 {
4548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4549 __func__, cipher);
4550 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4551 }
4552 else
4553 {
4554
4555 /*set encryption method*/
4556 switch (cipher)
4557 {
4558 case IW_AUTH_CIPHER_NONE:
4559 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4560 break;
4561
4562 case WLAN_CIPHER_SUITE_WEP40:
4563 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4564 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4565 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4566 else
4567 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4568 break;
4569
4570 case WLAN_CIPHER_SUITE_WEP104:
4571 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4572 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4573 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4574 else
4575 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4576 break;
4577
4578 case WLAN_CIPHER_SUITE_TKIP:
4579 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4580 break;
4581
4582 case WLAN_CIPHER_SUITE_CCMP:
4583 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4584 break;
4585#ifdef FEATURE_WLAN_WAPI
4586 case WLAN_CIPHER_SUITE_SMS4:
4587 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4588 break;
4589#endif
4590
4591#ifdef FEATURE_WLAN_CCX
4592 case WLAN_CIPHER_SUITE_KRK:
4593 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4594 break;
4595#endif
4596 default:
4597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4598 __func__, cipher);
4599 return -EOPNOTSUPP;
4600 }
4601 }
4602
4603 if (ucast)
4604 {
4605 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4606 __func__, encryptionType);
4607 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4608 pWextState->roamProfile.EncryptionType.numEntries = 1;
4609 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4610 encryptionType;
4611 }
4612 else
4613 {
4614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4615 __func__, encryptionType);
4616 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4617 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4618 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4619 }
4620
4621 return 0;
4622}
4623
4624
4625/*
4626 * FUNCTION: wlan_hdd_cfg80211_set_ie
4627 * This function is used to parse WPA/RSN IE's.
4628 */
4629int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4630 u8 *ie,
4631 size_t ie_len
4632 )
4633{
4634 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4635 u8 *genie = ie;
4636 v_U16_t remLen = ie_len;
4637#ifdef FEATURE_WLAN_WAPI
4638 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4639 u16 *tmp;
4640 v_U16_t akmsuiteCount;
4641 int *akmlist;
4642#endif
4643 ENTER();
4644
4645 /* clear previous assocAddIE */
4646 pWextState->assocAddIE.length = 0;
4647 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4648
4649 while (remLen >= 2)
4650 {
4651 v_U16_t eLen = 0;
4652 v_U8_t elementId;
4653 elementId = *genie++;
4654 eLen = *genie++;
4655 remLen -= 2;
4656
4657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4658 __func__, elementId, eLen);
4659
4660 switch ( elementId )
4661 {
4662 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004663 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 -07004664 {
4665 hddLog(VOS_TRACE_LEVEL_ERROR,
4666 "%s: Invalid WPA IE", __func__);
4667 return -EINVAL;
4668 }
4669 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4670 {
4671 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4672 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4673 __func__, eLen + 2);
4674
4675 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4676 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004677 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4678 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 VOS_ASSERT(0);
4680 return -ENOMEM;
4681 }
4682 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4683 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4684 pWextState->assocAddIE.length += eLen + 2;
4685
4686 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4687 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4688 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4689 }
4690 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4691 {
4692 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4693 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4694 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4695 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4696 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4697 }
4698#ifdef WLAN_FEATURE_P2P
4699 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4700 P2P_OUI_TYPE_SIZE))
4701 /*Consider P2P IE, only for P2P Client */
4702 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4703 {
4704 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4705 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4706 __func__, eLen + 2);
4707
4708 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4709 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004710 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4711 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004712 VOS_ASSERT(0);
4713 return -ENOMEM;
4714 }
4715 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4716 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4717 pWextState->assocAddIE.length += eLen + 2;
4718
4719 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4720 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4721 }
4722#endif
4723#ifdef WLAN_FEATURE_WFD
4724 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4725 WFD_OUI_TYPE_SIZE))
4726 /*Consider WFD IE, only for P2P Client */
4727 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4728 {
4729 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4730 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4731 __func__, eLen + 2);
4732
4733 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4734 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004735 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4736 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004737 VOS_ASSERT(0);
4738 return -ENOMEM;
4739 }
4740 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4741 // WPS IE + P2P IE + WFD IE
4742 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4743 pWextState->assocAddIE.length += eLen + 2;
4744
4745 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4746 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4747 }
4748#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004749 /* Appending HS 2.0 Indication Element in Assiciation Request */
4750 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004751 HS20_OUI_TYPE_SIZE)) )
4752 {
4753 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4754 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4755 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004756
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004757 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4758 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004759 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4760 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004761 VOS_ASSERT(0);
4762 return -ENOMEM;
4763 }
4764 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4765 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004766
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004767 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4768 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4769 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004770
Jeff Johnson295189b2012-06-20 16:38:30 -07004771 break;
4772 case DOT11F_EID_RSN:
4773 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4774 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4775 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4776 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4777 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4778 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004779 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4780 case DOT11F_EID_EXTCAP:
4781 {
4782 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4783 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
4784 __func__, eLen + 2);
4785
4786 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4787 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004788 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4789 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004790 VOS_ASSERT(0);
4791 return -ENOMEM;
4792 }
4793 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4794 pWextState->assocAddIE.length += eLen + 2;
4795
4796 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4797 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4798 break;
4799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004800#ifdef FEATURE_WLAN_WAPI
4801 case WLAN_EID_WAPI:
4802 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
4803 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
4804 pAdapter->wapi_info.nWapiMode);
4805 tmp = (u16 *)ie;
4806 tmp = tmp + 2; // Skip element Id and Len, Version
4807 akmsuiteCount = WPA_GET_LE16(tmp);
4808 tmp = tmp + 1;
4809 akmlist = (int *)(tmp);
4810 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
4811 {
4812 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
4813 }
4814 else
4815 {
4816 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
4817 VOS_ASSERT(0);
4818 return -EINVAL;
4819 }
4820
4821 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
4822 {
4823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004824 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
4826 }
4827 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
4828 {
4829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004830 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
4832 }
4833 break;
4834#endif
4835 default:
4836 hddLog (VOS_TRACE_LEVEL_ERROR,
4837 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004838 /* when Unknown IE is received we should break and continue
4839 * to the next IE in the buffer instead we were returning
4840 * so changing this to break */
4841 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07004842 }
4843 genie += eLen;
4844 remLen -= eLen;
4845 }
4846 EXIT();
4847 return 0;
4848}
4849
4850/*
4851 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4852 * This function is used to initialize the security
4853 * parameters during connect operation.
4854 */
4855int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
4856 struct cfg80211_connect_params *req
4857 )
4858{
4859 int status = 0;
4860 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4861 ENTER();
4862
4863 /*set wpa version*/
4864 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4865
4866 if (req->crypto.wpa_versions)
4867 {
4868 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
4869 && ( (req->ie_len)
4870 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
4871 // Make sure that it is including a WPA IE.
4872 /* Currently NL is putting WPA version 1 even for open,
4873 * since p2p ie is also put in same buffer.
4874 * */
4875 {
4876 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
4877 }
4878 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
4879 {
4880 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
4881 }
4882 }
4883
4884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
4885 pWextState->wpaVersion);
4886
4887 /*set authentication type*/
4888 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
4889
4890 if (0 > status)
4891 {
4892 hddLog(VOS_TRACE_LEVEL_ERROR,
4893 "%s: failed to set authentication type ", __func__);
4894 return status;
4895 }
4896
4897 /*set key mgmt type*/
4898 if (req->crypto.n_akm_suites)
4899 {
4900 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
4901 if (0 > status)
4902 {
4903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
4904 __func__);
4905 return status;
4906 }
4907 }
4908
4909 /*set pairwise cipher type*/
4910 if (req->crypto.n_ciphers_pairwise)
4911 {
4912 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
4913 req->crypto.ciphers_pairwise[0], true);
4914 if (0 > status)
4915 {
4916 hddLog(VOS_TRACE_LEVEL_ERROR,
4917 "%s: failed to set unicast cipher type", __func__);
4918 return status;
4919 }
4920 }
4921 else
4922 {
4923 /*Reset previous cipher suite to none*/
4924 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
4925 if (0 > status)
4926 {
4927 hddLog(VOS_TRACE_LEVEL_ERROR,
4928 "%s: failed to set unicast cipher type", __func__);
4929 return status;
4930 }
4931 }
4932
4933 /*set group cipher type*/
4934 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
4935 false);
4936
4937 if (0 > status)
4938 {
4939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
4940 __func__);
4941 return status;
4942 }
4943
4944 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
4945 if (req->ie_len)
4946 {
4947 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
4948 if ( 0 > status)
4949 {
4950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
4951 __func__);
4952 return status;
4953 }
4954 }
4955
4956 /*incase of WEP set default key information*/
4957 if (req->key && req->key_len)
4958 {
4959 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
4960 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
4961 )
4962 {
4963 if ( IW_AUTH_KEY_MGMT_802_1X
4964 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
4965 {
4966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
4967 __func__);
4968 return -EOPNOTSUPP;
4969 }
4970 else
4971 {
4972 u8 key_len = req->key_len;
4973 u8 key_idx = req->key_idx;
4974
4975 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
4976 && (CSR_MAX_NUM_KEY > key_idx)
4977 )
4978 {
4979 hddLog(VOS_TRACE_LEVEL_INFO,
4980 "%s: setting default wep key, key_idx = %hu key_len %hu",
4981 __func__, key_idx, key_len);
4982 vos_mem_copy(
4983 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
4984 req->key, key_len);
4985 pWextState->roamProfile.Keys.KeyLength[key_idx] =
4986 (u8)key_len;
4987 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
4988 }
4989 }
4990 }
4991 }
4992
4993 return status;
4994}
4995
4996/*
4997 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4998 * This function is used to initialize the security
4999 * parameters during connect operation.
5000 */
5001static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5002 struct net_device *ndev,
5003 struct cfg80211_connect_params *req
5004 )
5005{
5006 int status = 0;
5007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5008 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5009 hdd_context_t *pHddCtx = NULL;
5010
5011 ENTER();
5012
5013 hddLog(VOS_TRACE_LEVEL_INFO,
5014 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5015
5016 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5017 {
5018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5019 "%s:LOGP in Progress. Ignore!!!", __func__);
5020 return -EAGAIN;
5021 }
5022
5023#ifdef WLAN_BTAMP_FEATURE
5024 //Infra connect not supported when AMP traffic is on.
5025 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5026 {
5027 hddLog(VOS_TRACE_LEVEL_ERROR,
5028 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005029 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005030 }
5031#endif
5032 /*initialise security parameters*/
5033 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5034
5035 if ( 0 > status)
5036 {
5037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5038 __func__);
5039 return status;
5040 }
5041
5042 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005043 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005044 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5045 (vos_concurrent_sessions_running()))
5046 {
5047 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5048
5049 if (NULL != pVosContext)
5050 {
5051 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5052 if(NULL != pHddCtx)
5053 {
5054 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5055 }
5056 }
5057 }
5058
Mohit Khanna765234a2012-09-11 15:08:35 -07005059 if ( req->channel )
5060 {
5061 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5062 req->ssid_len, req->bssid,
5063 req->channel->hw_value);
5064 }
5065 else
5066 {
5067 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5068 req->ssid_len, req->bssid,
5069 0);
5070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005071
5072 if (0 > status)
5073 {
5074 //ReEnable BMPS if disabled
5075 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5076 (NULL != pHddCtx))
5077 {
5078 //ReEnable Bmps and Imps back
5079 hdd_enable_bmps_imps(pHddCtx);
5080 }
5081
5082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5083 return status;
5084 }
5085 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5086 EXIT();
5087 return status;
5088}
5089
5090
5091/*
5092 * FUNCTION: wlan_hdd_cfg80211_disconnect
5093 * This function is used to issue a disconnect request to SME
5094 */
5095static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5096 struct net_device *dev,
5097 u16 reason
5098 )
5099{
5100 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5101 tCsrRoamProfile *pRoamProfile =
5102 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5103 int status = 0;
5104 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5105
5106 ENTER();
5107
5108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5109 __func__,pAdapter->device_mode);
5110
5111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5112 __func__, reason);
5113
5114 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5115 {
5116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5117 "%s:LOGP in Progress. Ignore!!!",__func__);
5118 return -EAGAIN;
5119 }
5120 if (NULL != pRoamProfile)
5121 {
5122 /*issue disconnect request to SME, if station is in connected state*/
5123 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5124 {
5125 eCsrRoamDisconnectReason reasonCode =
5126 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5127 switch(reason)
5128 {
5129 case WLAN_REASON_MIC_FAILURE:
5130 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5131 break;
5132
5133 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5134 case WLAN_REASON_DISASSOC_AP_BUSY:
5135 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5136 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5137 break;
5138
5139 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5140 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5141 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5142 break;
5143
5144 case WLAN_REASON_DEAUTH_LEAVING:
5145 default:
5146 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5147 break;
5148 }
5149 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5150 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5151 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5152
5153 /*issue disconnect*/
5154 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5155 pAdapter->sessionId, reasonCode);
5156
5157 if ( 0 != status)
5158 {
5159 hddLog(VOS_TRACE_LEVEL_ERROR,
5160 "%s csrRoamDisconnect failure, returned %d \n",
5161 __func__, (int)status );
5162 return -EINVAL;
5163 }
5164
5165 wait_for_completion_interruptible_timeout(
5166 &pAdapter->disconnect_comp_var,
5167 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5168
5169
5170 /*stop tx queues*/
5171 netif_tx_disable(dev);
5172 netif_carrier_off(dev);
5173 }
5174 }
5175 else
5176 {
5177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5178 }
5179
5180 return status;
5181}
5182
5183/*
5184 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5185 * This function is used to initialize the security
5186 * settings in IBSS mode.
5187 */
5188static int wlan_hdd_cfg80211_set_privacy_ibss(
5189 hdd_adapter_t *pAdapter,
5190 struct cfg80211_ibss_params *params
5191 )
5192{
5193 int status = 0;
5194 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5195 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5196 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5197
5198 ENTER();
5199
5200 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5201
5202 if (params->ie_len && ( NULL != params->ie) )
5203 {
5204 if (WLAN_EID_RSN == params->ie[0])
5205 {
5206 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5207 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5208 }
5209 else
5210 {
5211 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5212 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5213 }
5214 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5215
5216 if (0 > status)
5217 {
5218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5219 __func__);
5220 return status;
5221 }
5222 }
5223
5224 pWextState->roamProfile.AuthType.authType[0] =
5225 pHddStaCtx->conn_info.authType =
5226 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5227
5228 if (params->privacy)
5229 {
5230 /* Security enabled IBSS, At this time there is no information available
5231 * about the security paramters, so initialise the encryption type to
5232 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5233 * The correct security parameters will be updated later in
5234 * wlan_hdd_cfg80211_add_key */
5235 /* Hal expects encryption type to be set inorder
5236 *enable privacy bit in beacons */
5237
5238 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5239 }
5240
5241 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5242 pWextState->roamProfile.EncryptionType.numEntries = 1;
5243 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5244
5245 return status;
5246}
5247
5248/*
5249 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5250 * This function is used to create/join an IBSS
5251 */
5252static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5253 struct net_device *dev,
5254 struct cfg80211_ibss_params *params
5255 )
5256{
5257 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5258 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5259 tCsrRoamProfile *pRoamProfile;
5260 int status;
5261 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5262
5263 ENTER();
5264
5265 hddLog(VOS_TRACE_LEVEL_INFO,
5266 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5267
5268 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5269 {
5270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5271 "%s:LOGP in Progress. Ignore!!!", __func__);
5272 return -EAGAIN;
5273 }
5274
5275 if (NULL == pWextState)
5276 {
5277 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5278 __func__);
5279 return -EIO;
5280 }
5281
5282 pRoamProfile = &pWextState->roamProfile;
5283
5284 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5285 {
5286 hddLog (VOS_TRACE_LEVEL_ERROR,
5287 "%s Interface type is not set to IBSS \n", __func__);
5288 return -EINVAL;
5289 }
5290
5291 /* Set Channel */
5292 if (NULL != params->channel)
5293 {
5294 u8 channelNum;
5295 if (IEEE80211_BAND_5GHZ == params->channel->band)
5296 {
5297 hddLog(VOS_TRACE_LEVEL_ERROR,
5298 "%s: IBSS join is called with unsupported band %d",
5299 __func__, params->channel->band);
5300 return -EOPNOTSUPP;
5301 }
5302
5303 /* Get channel number */
5304 channelNum =
5305 ieee80211_frequency_to_channel(params->channel->center_freq);
5306
5307 /*TODO: use macro*/
5308 if (14 >= channelNum)
5309 {
5310 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5311 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5312 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5313 int indx;
5314
5315 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5316 validChan, &numChans))
5317 {
5318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5319 __func__);
5320 return -EOPNOTSUPP;
5321 }
5322
5323 for (indx = 0; indx < numChans; indx++)
5324 {
5325 if (channelNum == validChan[indx])
5326 {
5327 break;
5328 }
5329 }
5330 if (indx >= numChans)
5331 {
5332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5333 __func__, channelNum);
5334 return -EINVAL;
5335 }
5336 /* Set the Operational Channel */
5337 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5338 channelNum);
5339 pRoamProfile->ChannelInfo.numOfChannels = 1;
5340 pHddStaCtx->conn_info.operationChannel = channelNum;
5341 pRoamProfile->ChannelInfo.ChannelList =
5342 &pHddStaCtx->conn_info.operationChannel;
5343 }
5344 else
5345 {
5346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5347 __func__, channelNum);
5348 return -EINVAL;
5349 }
5350 }
5351
5352 /* Initialize security parameters */
5353 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5354 if (status < 0)
5355 {
5356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5357 __func__);
5358 return status;
5359 }
5360
5361 /* Issue connect start */
5362 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005363 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005364
5365 if (0 > status)
5366 {
5367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5368 return status;
5369 }
5370
5371 return 0;
5372}
5373
5374/*
5375 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5376 * This function is used to leave an IBSS
5377 */
5378static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5379 struct net_device *dev
5380 )
5381{
5382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5383 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5384 tCsrRoamProfile *pRoamProfile;
5385
5386 ENTER();
5387
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005388 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5389 {
5390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5391 "%s:LOGP in Progress. Ignore!!!", __func__);
5392 return -EAGAIN;
5393 }
5394
Jeff Johnson295189b2012-06-20 16:38:30 -07005395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5396 if (NULL == pWextState)
5397 {
5398 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5399 __func__);
5400 return -EIO;
5401 }
5402
5403 pRoamProfile = &pWextState->roamProfile;
5404
5405 /* Issue disconnect only if interface type is set to IBSS */
5406 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5407 {
5408 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5409 __func__);
5410 return -EINVAL;
5411 }
5412
5413 /* Issue Disconnect request */
5414 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5415 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5416 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5417
5418 return 0;
5419}
5420
5421/*
5422 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5423 * This function is used to set the phy parameters
5424 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5425 */
5426static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5427 u32 changed)
5428{
5429 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5430 tHalHandle hHal = pHddCtx->hHal;
5431
5432 ENTER();
5433
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005434 if ( pHddCtx->isLogpInProgress )
5435 {
5436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5437 "%s:LOGP in Progress. Ignore!!!", __func__);
5438 return -EAGAIN;
5439 }
5440
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5442 {
5443 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5444 WNI_CFG_RTS_THRESHOLD_STAMAX :
5445 wiphy->rts_threshold;
5446
5447 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5448 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5449 {
5450 hddLog(VOS_TRACE_LEVEL_ERROR,
5451 "%s: Invalid RTS Threshold value %hu",
5452 __func__, rts_threshold);
5453 return -EINVAL;
5454 }
5455
5456 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5457 rts_threshold, ccmCfgSetCallback,
5458 eANI_BOOLEAN_TRUE))
5459 {
5460 hddLog(VOS_TRACE_LEVEL_ERROR,
5461 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5462 __func__, rts_threshold);
5463 return -EIO;
5464 }
5465
5466 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5467 rts_threshold);
5468 }
5469
5470 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5471 {
5472 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5473 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5474 wiphy->frag_threshold;
5475
5476 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5477 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5478 {
5479 hddLog(VOS_TRACE_LEVEL_ERROR,
5480 "%s: Invalid frag_threshold value %hu", __func__,
5481 frag_threshold);
5482 return -EINVAL;
5483 }
5484
5485 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5486 frag_threshold, ccmCfgSetCallback,
5487 eANI_BOOLEAN_TRUE))
5488 {
5489 hddLog(VOS_TRACE_LEVEL_ERROR,
5490 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5491 __func__, frag_threshold);
5492 return -EIO;
5493 }
5494
5495 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5496 frag_threshold);
5497 }
5498
5499 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5500 || (changed & WIPHY_PARAM_RETRY_LONG))
5501 {
5502 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5503 wiphy->retry_short :
5504 wiphy->retry_long;
5505
5506 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5507 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5508 {
5509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5510 __func__, retry_value);
5511 return -EINVAL;
5512 }
5513
5514 if (changed & WIPHY_PARAM_RETRY_SHORT)
5515 {
5516 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5517 retry_value, ccmCfgSetCallback,
5518 eANI_BOOLEAN_TRUE))
5519 {
5520 hddLog(VOS_TRACE_LEVEL_ERROR,
5521 "%s: ccmCfgSetInt failed for long retry count %hu",
5522 __func__, retry_value);
5523 return -EIO;
5524 }
5525 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5526 __func__, retry_value);
5527 }
5528 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5529 {
5530 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5531 retry_value, ccmCfgSetCallback,
5532 eANI_BOOLEAN_TRUE))
5533 {
5534 hddLog(VOS_TRACE_LEVEL_ERROR,
5535 "%s: ccmCfgSetInt failed for short retry count %hu",
5536 __func__, retry_value);
5537 return -EIO;
5538 }
5539 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5540 __func__, retry_value);
5541 }
5542 }
5543
5544 return 0;
5545}
5546
5547/*
5548 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5549 * This function is used to set the txpower
5550 */
5551static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5552#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5553 enum tx_power_setting type,
5554#else
5555 enum nl80211_tx_power_setting type,
5556#endif
5557 int dbm)
5558{
5559 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5560 tHalHandle hHal = pHddCtx->hHal;
5561 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5562 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5563
5564 ENTER();
5565
5566 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5567 dbm, ccmCfgSetCallback,
5568 eANI_BOOLEAN_TRUE))
5569 {
5570 hddLog(VOS_TRACE_LEVEL_ERROR,
5571 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5572 return -EIO;
5573 }
5574
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005575 if ( pHddCtx->isLogpInProgress )
5576 {
5577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5578 "%s:LOGP in Progress. Ignore!!!", __func__);
5579 return -EAGAIN;
5580 }
5581
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5583 dbm);
5584
5585 switch(type)
5586 {
5587 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5588 /* Fall through */
5589 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5590 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5591 {
5592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5593 __func__);
5594 return -EIO;
5595 }
5596 break;
5597 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5599 __func__);
5600 return -EOPNOTSUPP;
5601 break;
5602 default:
5603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5604 __func__, type);
5605 return -EIO;
5606 }
5607
5608 return 0;
5609}
5610
5611/*
5612 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5613 * This function is used to read the txpower
5614 */
5615static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5616{
5617
5618 hdd_adapter_t *pAdapter;
5619 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5620
Jeff Johnsone7245742012-09-05 17:12:55 -07005621 ENTER();
5622
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 if (NULL == pHddCtx)
5624 {
5625 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5626 *dbm = 0;
5627 return -ENOENT;
5628 }
5629
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005630 if ( pHddCtx->isLogpInProgress )
5631 {
5632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5633 "%s:LOGP in Progress. Ignore!!!", __func__);
5634 return -EAGAIN;
5635 }
5636
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5638 if (NULL == pAdapter)
5639 {
5640 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5641 return -ENOENT;
5642 }
5643
5644 wlan_hdd_get_classAstats(pAdapter);
5645 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5646
Jeff Johnsone7245742012-09-05 17:12:55 -07005647 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 return 0;
5649}
5650
5651static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5652 u8* mac, struct station_info *sinfo)
5653{
5654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5655 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5656 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5657 tANI_U8 rate_flags;
5658
5659 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5660 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5661 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5662
5663 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5664 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5665 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5666 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5667 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5668 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5669 tANI_U16 maxRate = 0;
5670 tANI_U16 myRate;
5671 tANI_U16 currentRate = 0;
5672 tANI_U8 maxSpeedMCS = 0;
5673 tANI_U8 maxMCSIdx = 0;
5674 tANI_U8 rateFlag = 1;
5675 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005676 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005677
Jeff Johnsone7245742012-09-05 17:12:55 -07005678 ENTER();
5679
Jeff Johnson295189b2012-06-20 16:38:30 -07005680 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5681 (0 == ssidlen))
5682 {
5683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5684 " Invalid ssidlen, %d", __func__, ssidlen);
5685 /*To keep GUI happy*/
5686 return 0;
5687 }
5688
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005689 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5690 {
5691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5692 "%s:LOGP in Progress. Ignore!!!", __func__);
5693 return -EAGAIN;
5694 }
5695
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5697 sinfo->filled |= STATION_INFO_SIGNAL;
5698
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005699 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5701
5702 //convert to the UI units of 100kbps
5703 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5704
5705#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005706 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 sinfo->signal,
5708 pCfg->reportMaxLinkSpeed,
5709 myRate,
5710 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005711 (int) pCfg->linkSpeedRssiMid,
5712 (int) pCfg->linkSpeedRssiLow,
5713 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005714#endif //LINKSPEED_DEBUG_ENABLED
5715
5716 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5717 {
5718 // we do not want to necessarily report the current speed
5719 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5720 {
5721 // report the max possible speed
5722 rssidx = 0;
5723 }
5724 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5725 {
5726 // report the max possible speed with RSSI scaling
5727 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5728 {
5729 // report the max possible speed
5730 rssidx = 0;
5731 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005732 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 {
5734 // report middle speed
5735 rssidx = 1;
5736 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005737 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5738 {
5739 // report middle speed
5740 rssidx = 2;
5741 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 else
5743 {
5744 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005745 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 }
5747 }
5748 else
5749 {
5750 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5751 hddLog(VOS_TRACE_LEVEL_ERROR,
5752 "%s: Invalid value for reportMaxLinkSpeed: %u",
5753 __func__, pCfg->reportMaxLinkSpeed);
5754 rssidx = 0;
5755 }
5756
5757 maxRate = 0;
5758
5759 /* Get Basic Rate Set */
5760 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5761 for (i = 0; i < ORLeng; i++)
5762 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005763 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 {
5765 /* Validate Rate Set */
5766 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5767 {
5768 currentRate = supported_data_rate[j].supported_rate[rssidx];
5769 break;
5770 }
5771 }
5772 /* Update MAX rate */
5773 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5774 }
5775
5776 /* Get Extended Rate Set */
5777 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5778 for (i = 0; i < ERLeng; i++)
5779 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005780 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 {
5782 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
5783 {
5784 currentRate = supported_data_rate[j].supported_rate[rssidx];
5785 break;
5786 }
5787 }
5788 /* Update MAX rate */
5789 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5790 }
5791
5792 /* Get MCS Rate Set -- but only if we are connected at MCS
5793 rates or if we are always reporting max speed or if we have
5794 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005795 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07005796 {
5797 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
5798 rateFlag = 0;
5799 if (rate_flags & eHAL_TX_RATE_HT40)
5800 {
5801 rateFlag |= 1;
5802 }
5803 if (rate_flags & eHAL_TX_RATE_SGI)
5804 {
5805 rateFlag |= 2;
5806 }
5807
5808 for (i = 0; i < MCSLeng; i++)
5809 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005810 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
5811 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 {
5813 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
5814 {
5815 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
5816 break;
5817 }
5818 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005819 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 {
5821 maxRate = currentRate;
5822 maxSpeedMCS = 1;
5823 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
5824 }
5825 }
5826 }
5827
5828 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005829 if (((maxRate < myRate) && (0 == rssidx)) ||
5830 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 {
5832 maxRate = myRate;
5833 if (rate_flags & eHAL_TX_RATE_LEGACY)
5834 {
5835 maxSpeedMCS = 0;
5836 }
5837 else
5838 {
5839 maxSpeedMCS = 1;
5840 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5841 }
5842 }
5843
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005844 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 {
5846 sinfo->txrate.legacy = maxRate;
5847#ifdef LINKSPEED_DEBUG_ENABLED
5848 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
5849#endif //LINKSPEED_DEBUG_ENABLED
5850 }
5851 else
5852 {
5853 sinfo->txrate.mcs = maxMCSIdx;
5854 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5855 if (rate_flags & eHAL_TX_RATE_SGI)
5856 {
5857 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5858 }
5859 if (rate_flags & eHAL_TX_RATE_HT40)
5860 {
5861 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5862 }
5863#ifdef LINKSPEED_DEBUG_ENABLED
5864 pr_info("Reporting MCS rate %d flags %x\n",
5865 sinfo->txrate.mcs,
5866 sinfo->txrate.flags );
5867#endif //LINKSPEED_DEBUG_ENABLED
5868 }
5869 }
5870 else
5871 {
5872 // report current rate instead of max rate
5873
5874 if (rate_flags & eHAL_TX_RATE_LEGACY)
5875 {
5876 //provide to the UI in units of 100kbps
5877 sinfo->txrate.legacy = myRate;
5878#ifdef LINKSPEED_DEBUG_ENABLED
5879 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
5880#endif //LINKSPEED_DEBUG_ENABLED
5881 }
5882 else
5883 {
5884 //must be MCS
5885 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5886 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5887 if (rate_flags & eHAL_TX_RATE_SGI)
5888 {
5889 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5890 }
5891 if (rate_flags & eHAL_TX_RATE_HT40)
5892 {
5893 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5894 }
5895#ifdef LINKSPEED_DEBUG_ENABLED
5896 pr_info("Reporting actual MCS rate %d flags %x\n",
5897 sinfo->txrate.mcs,
5898 sinfo->txrate.flags );
5899#endif //LINKSPEED_DEBUG_ENABLED
5900 }
5901 }
5902 sinfo->filled |= STATION_INFO_TX_BITRATE;
5903
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005904 sinfo->tx_packets =
5905 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
5906 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
5907 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
5908 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
5909
5910 sinfo->tx_retries =
5911 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
5912 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
5913 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
5914 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
5915
5916 sinfo->tx_failed =
5917 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
5918 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
5919 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
5920 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
5921
5922 sinfo->filled |=
5923 STATION_INFO_TX_PACKETS |
5924 STATION_INFO_TX_RETRIES |
5925 STATION_INFO_TX_FAILED;
5926
5927 EXIT();
5928 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005929}
5930
5931static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
5932 struct net_device *dev, bool mode, v_SINT_t timeout)
5933{
5934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5935 VOS_STATUS vos_status;
5936
Jeff Johnsone7245742012-09-05 17:12:55 -07005937 ENTER();
5938
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 if (NULL == pAdapter)
5940 {
5941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5942 return -ENODEV;
5943 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005944 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5945 {
5946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5947 "%s:LOGP in Progress. Ignore!!!", __func__);
5948 return -EAGAIN;
5949 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005950
5951 /**The get power cmd from the supplicant gets updated by the nl only
5952 *on successful execution of the function call
5953 *we are oppositely mapped w.r.t mode in the driver
5954 **/
5955 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
5956
Jeff Johnsone7245742012-09-05 17:12:55 -07005957 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 if (VOS_STATUS_E_FAILURE == vos_status)
5959 {
5960 return -EINVAL;
5961 }
5962 return 0;
5963}
5964
5965
5966#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5967static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
5968 struct net_device *netdev,
5969 u8 key_index)
5970{
Jeff Johnsone7245742012-09-05 17:12:55 -07005971 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 return 0;
5973}
5974#endif //LINUX_VERSION_CODE
5975
5976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5977static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5978 struct net_device *dev,
5979 struct ieee80211_txq_params *params)
5980{
Jeff Johnsone7245742012-09-05 17:12:55 -07005981 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 return 0;
5983}
5984#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5985static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5986 struct ieee80211_txq_params *params)
5987{
Jeff Johnsone7245742012-09-05 17:12:55 -07005988 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 return 0;
5990}
5991#endif //LINUX_VERSION_CODE
5992
5993static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
5994 struct net_device *dev, u8 *mac)
5995{
5996 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5997
Jeff Johnsone7245742012-09-05 17:12:55 -07005998 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6000 {
6001 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6002 return -EINVAL;
6003 }
6004
6005 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6006 {
6007 hddLog( LOGE,
6008 "%s: Wlan Load/Unload is in progress", __func__);
6009 return -EBUSY;
6010 }
6011
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006012 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6013 {
6014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6015 "%s:LOGP in Progress. Ignore!!!", __func__);
6016 return -EAGAIN;
6017 }
6018
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6020#ifdef WLAN_FEATURE_P2P
6021 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6022#endif
6023 )
6024 {
6025 if( NULL == mac )
6026 {
6027 v_U16_t i;
6028 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6029 {
6030 if(pAdapter->aStaInfo[i].isUsed)
6031 {
6032 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6033 hddLog(VOS_TRACE_LEVEL_INFO,
6034 "%s: Delete STA with MAC::"
6035 "%02x:%02x:%02x:%02x:%02x:%02x",
6036 __func__,
6037 macAddr[0], macAddr[1], macAddr[2],
6038 macAddr[3], macAddr[4], macAddr[5]);
6039 hdd_softap_sta_deauth(pAdapter, macAddr);
6040 }
6041 }
6042 }
6043 else
6044 {
6045 hddLog(VOS_TRACE_LEVEL_INFO,
6046 "%s: Delete STA with MAC::"
6047 "%02x:%02x:%02x:%02x:%02x:%02x",
6048 __func__,
6049 mac[0], mac[1], mac[2],
6050 mac[3], mac[4], mac[5]);
6051 hdd_softap_sta_deauth(pAdapter, mac);
6052 }
6053 }
6054
6055 EXIT();
6056
6057 return 0;
6058}
6059
6060static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6061 struct net_device *dev, u8 *mac, struct station_parameters *params)
6062{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006063#ifdef FEATURE_WLAN_TDLS
6064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6065 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6066 u32 mask, set;
6067 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006068 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006069
6070 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6071 {
6072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6073 "Invalid arguments");
6074 return -EINVAL;
6075 }
6076
6077 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6078 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6079 {
6080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6081 "TDLS Disabled in INI OR not enabled in FW.\
6082 Cannot process TDLS commands \n");
6083 return -ENOTSUPP;
6084 }
6085
6086 mask = params->sta_flags_mask;
6087
6088 set = params->sta_flags_set;
6089
6090
6091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6092 "Add Station Request Mask = 0x%x set = 0x%x\n", mask, set);
6093
6094 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6095 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6097 "Add TDLS peer");
6098
6099
6100 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6101 pAdapter->sessionId, mac);
6102
6103 if (VOS_STATUS_SUCCESS != status) {
6104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6105 "%s: sme_AddTdlsPeerSta failed!", __func__);
6106 }
6107 }
6108 }
6109#endif
6110
Jeff Johnson295189b2012-06-20 16:38:30 -07006111 return 0;
6112}
6113
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006114
6115#ifdef FEATURE_WLAN_LFR
6116static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006117 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006118{
6119#define MAX_PMKSAIDS_IN_CACHE 8
6120 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006121 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006122 tANI_U32 j=0;
6123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6124 tHalHandle halHandle;
6125 eHalStatus result;
6126 tANI_U8 BSSIDMatched = 0;
6127
Jeff Johnsone7245742012-09-05 17:12:55 -07006128 ENTER();
6129
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006130 // Validate pAdapter
6131 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6132 {
6133 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6134 return -EINVAL;
6135 }
6136
6137 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6138 {
6139 hddLog( LOGE,
6140 "%s: Wlan Load/Unload is in progress", __func__);
6141 return -EBUSY;
6142 }
6143
6144 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6145 {
6146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6147 "%s:LOGP in Progress. Ignore!!!", __func__);
6148 return -EAGAIN;
6149 }
6150
6151 // Retrieve halHandle
6152 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6153
6154 for (j = 0; j < i; j++)
6155 {
6156 if(vos_mem_compare(PMKIDCache[j].BSSID,
6157 pmksa->bssid, WNI_CFG_BSSID_LEN))
6158 {
6159 /* BSSID matched previous entry. Overwrite it. */
6160 BSSIDMatched = 1;
6161 vos_mem_copy(PMKIDCache[j].BSSID,
6162 pmksa->bssid, WNI_CFG_BSSID_LEN);
6163 vos_mem_copy(PMKIDCache[j].PMKID,
6164 pmksa->pmkid,
6165 CSR_RSN_PMKID_SIZE);
6166 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006167 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006168 dump_bssid(pmksa->bssid);
6169 dump_pmkid(halHandle, pmksa->pmkid);
6170 break;
6171 }
6172 }
6173
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006174 /* Check we compared all entries,if then take the first slot now */
6175 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6176
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006177 if (!BSSIDMatched)
6178 {
6179 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6180 vos_mem_copy(PMKIDCache[i].BSSID,
6181 pmksa->bssid, ETHER_ADDR_LEN);
6182 vos_mem_copy(PMKIDCache[i].PMKID,
6183 pmksa->pmkid,
6184 CSR_RSN_PMKID_SIZE);
6185 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006186 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006187 dump_bssid(pmksa->bssid);
6188 dump_pmkid(halHandle, pmksa->pmkid);
6189 // Increment the HDD Local Cache index
6190 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6191 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6192 }
6193
6194
6195 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6196 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006197 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006198 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006199 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006200 // Finally set the PMKSA ID Cache in CSR
6201 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6202 PMKIDCache,
6203 i );
6204 return 0;
6205}
6206
6207
6208static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006209 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006210{
Jeff Johnsone7245742012-09-05 17:12:55 -07006211 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006212 // TODO: Implement this later.
6213 return 0;
6214}
6215
6216static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6217{
Jeff Johnsone7245742012-09-05 17:12:55 -07006218 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006219 // TODO: Implement this later.
6220 return 0;
6221}
6222#endif
6223
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006224#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6225static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6226 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6227{
6228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6229 hdd_station_ctx_t *pHddStaCtx;
6230
6231 if (NULL == pAdapter)
6232 {
6233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6234 return -ENODEV;
6235 }
6236
6237 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6238
6239 // Added for debug on reception of Re-assoc Req.
6240 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6241 {
6242 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6243 ftie->ie_len);
6244 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6245 }
6246
6247#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6248 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6249 ftie->ie_len);
6250#endif
6251
6252 // Pass the received FT IEs to SME
6253 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6254 ftie->ie_len);
6255 return 0;
6256}
6257#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006258
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006259#ifdef FEATURE_WLAN_TDLS
6260static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6261 u8 *peer, u8 action_code, u8 dialog_token,
6262 u16 status_code, const u8 *buf, size_t len)
6263{
6264
6265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6266 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6267 u8 *buf_1;
6268 size_t len_1 = len;
6269 u8 peerMac[6];
6270 VOS_STATUS status;
6271
6272 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6273 {
6274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6275 "Invalid arguments");
6276 return -EINVAL;
6277 }
6278
6279 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6280 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6281 {
6282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6283 "TDLS Disabled in INI OR not enabled in FW.\
6284 Cannot process TDLS commands \n");
6285 return -ENOTSUPP;
6286 }
6287 vos_mem_copy( peerMac, peer, 6);
6288
6289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6290 "Request to send TDLS management: action = %d, status = %d, \
Ng Chilamfc416462012-12-27 17:26:52 -08006291 len = %d", action_code, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006292
6293 buf_1 = vos_mem_malloc(len);
6294 if(buf_1 == NULL) {
6295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6296 "%s: malloc failed!", __func__);
6297 return -ENOMEM;
6298 }
6299 vos_mem_copy(buf_1, buf, len);
6300
6301 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6302 peerMac, action_code, dialog_token, status_code, buf_1, len_1);
6303
6304 if (VOS_STATUS_SUCCESS != status) {
6305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6306 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6307 }
6308
6309 vos_mem_free(buf_1);
6310
6311 return 0;
6312}
6313
6314static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6315 u8 *peer, enum nl80211_tdls_operation oper)
6316{
6317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6318 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6319
6320 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6321 {
6322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6323 "Invalid arguments");
6324 return -EINVAL;
6325 }
6326
6327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6328 "Request for TDLS oper: %d", (int)oper);
6329
6330 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6331 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6332 {
6333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6334 "TDLS Disabled in INI OR not enabled in FW.\
6335 Cannot process TDLS commands \n");
6336 return -ENOTSUPP;
6337 }
6338
6339 switch (oper) {
6340 case NL80211_TDLS_ENABLE_LINK:
6341 {
6342 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
6343 v_U8_t my_peer[6];
6344 v_U8_t ucSTAId;
6345 VOS_STATUS status;
6346
6347 if (peer) {
6348 vos_mem_copy(my_peer, peer, 6);
6349 ucSTAId = wlan_hdd_findTdlsPeer(my_peer);
6350
6351 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6352 "%s: set key for peer %2x:%2x:%2x:%2x:%2x:%2x",
6353 __func__, peer[0], peer[1],
6354 peer[2], peer[3],
6355 peer[4], peer[5] );
6356
6357 if (-1 == ucSTAId ) {
6358 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan_hdd_findTdlsPeer failed" );
6359 return 0;
6360 }
6361
6362 status = WLANTL_ChangeSTAState( pVosContext, ucSTAId,
6363 WLANTL_STA_AUTHENTICATED );
6364
6365 if (0 != status) {
6366 hddLog(VOS_TRACE_LEVEL_ERROR,
6367 "%s: WLANTL_ChangeSTAState failed, returned %d",
6368 __func__, status);
6369 return status;
6370 }
6371 } else {
6372 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6373 }
6374 }
6375 break;
6376 case NL80211_TDLS_DISABLE_LINK:
6377 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6378 pAdapter->sessionId, peer );
6379 return 0;
6380 case NL80211_TDLS_TEARDOWN:
6381 case NL80211_TDLS_SETUP:
6382 case NL80211_TDLS_DISCOVERY_REQ:
6383 /* We don't support in-driver setup/teardown/discovery */
6384 return -ENOTSUPP;
6385 default:
6386 return -ENOTSUPP;
6387 }
6388 return 0;
6389}
6390#endif
6391
Jeff Johnson295189b2012-06-20 16:38:30 -07006392/* cfg80211_ops */
6393static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6394{
6395 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6396 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6397 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6398 .change_station = wlan_hdd_change_station,
6399#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6400 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6401 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6402 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006403#else
6404 .start_ap = wlan_hdd_cfg80211_start_ap,
6405 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6406 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006407#endif
6408 .change_bss = wlan_hdd_cfg80211_change_bss,
6409 .add_key = wlan_hdd_cfg80211_add_key,
6410 .get_key = wlan_hdd_cfg80211_get_key,
6411 .del_key = wlan_hdd_cfg80211_del_key,
6412 .set_default_key = wlan_hdd_cfg80211_set_default_key,
6413 .set_channel = wlan_hdd_cfg80211_set_channel,
6414 .scan = wlan_hdd_cfg80211_scan,
6415 .connect = wlan_hdd_cfg80211_connect,
6416 .disconnect = wlan_hdd_cfg80211_disconnect,
6417 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6418 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6419 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6420 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6421 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6422#ifdef WLAN_FEATURE_P2P
6423 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6424 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6425 .mgmt_tx = wlan_hdd_action,
6426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6427 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6428 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6429 .set_txq_params = wlan_hdd_set_txq_params,
6430#endif
6431#endif
6432 .get_station = wlan_hdd_cfg80211_get_station,
6433 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6434 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006435 .add_station = wlan_hdd_cfg80211_add_station,
6436#ifdef FEATURE_WLAN_LFR
6437 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6438 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6439 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6440#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006441#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6442 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6443#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006444#ifdef FEATURE_WLAN_TDLS
6445 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6446 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6447#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006448};
6449
6450#endif // CONFIG_CFG80211