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