blob: a45e877c7de802a9dd14b6902ac8671580f4fc8d [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"
79#ifdef WLAN_BTAMP_FEATURE
80#include "bap_hdd_misc.h"
81#endif
82#include <qc_sap_ioctl.h>
83
84#define g_mode_rates_size (12)
85#define a_mode_rates_size (8)
86#define FREQ_BASE_80211G (2407)
87#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070088#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070089#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
90 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
91
92#define HDD2GHZCHAN(freq, chan, flag) { \
93 .band = IEEE80211_BAND_2GHZ, \
94 .center_freq = (freq), \
95 .hw_value = (chan),\
96 .flags = (flag), \
97 .max_antenna_gain = 0 ,\
98 .max_power = 30, \
99}
100
101#define HDD5GHZCHAN(freq, chan, flag) { \
102 .band = IEEE80211_BAND_5GHZ, \
103 .center_freq = (freq), \
104 .hw_value = (chan),\
105 .flags = (flag), \
106 .max_antenna_gain = 0 ,\
107 .max_power = 30, \
108}
109
110#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
111{\
112 .bitrate = rate, \
113 .hw_value = rate_id, \
114 .flags = flag, \
115}
116
117static const u32 hdd_cipher_suites[] =
118{
119 WLAN_CIPHER_SUITE_WEP40,
120 WLAN_CIPHER_SUITE_WEP104,
121 WLAN_CIPHER_SUITE_TKIP,
122#ifdef FEATURE_WLAN_CCX
123#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
124 WLAN_CIPHER_SUITE_KRK,
125 WLAN_CIPHER_SUITE_CCMP,
126#else
127 WLAN_CIPHER_SUITE_CCMP,
128#endif
129#ifdef FEATURE_WLAN_WAPI
130 WLAN_CIPHER_SUITE_SMS4,
131#endif
132};
133
134static inline int is_broadcast_ether_addr(const u8 *addr)
135{
136 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
137 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
138}
139
140static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
141{
142 HDD2GHZCHAN(2412, 1, 0) ,
143 HDD2GHZCHAN(2417, 2, 0) ,
144 HDD2GHZCHAN(2422, 3, 0) ,
145 HDD2GHZCHAN(2427, 4, 0) ,
146 HDD2GHZCHAN(2432, 5, 0) ,
147 HDD2GHZCHAN(2437, 6, 0) ,
148 HDD2GHZCHAN(2442, 7, 0) ,
149 HDD2GHZCHAN(2447, 8, 0) ,
150 HDD2GHZCHAN(2452, 9, 0) ,
151 HDD2GHZCHAN(2457, 10, 0) ,
152 HDD2GHZCHAN(2462, 11, 0) ,
153 HDD2GHZCHAN(2467, 12, 0) ,
154 HDD2GHZCHAN(2472, 13, 0) ,
155 HDD2GHZCHAN(2484, 14, 0) ,
156};
157
158#ifdef WLAN_FEATURE_P2P
159static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
160{
161 HDD2GHZCHAN(2412, 1, 0) ,
162 HDD2GHZCHAN(2437, 6, 0) ,
163 HDD2GHZCHAN(2462, 11, 0) ,
164};
165#endif
166
167static struct ieee80211_channel hdd_channels_5_GHZ[] =
168{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700169 HDD5GHZCHAN(4920, 240, 0) ,
170 HDD5GHZCHAN(4940, 244, 0) ,
171 HDD5GHZCHAN(4960, 248, 0) ,
172 HDD5GHZCHAN(4980, 252, 0) ,
173 HDD5GHZCHAN(5040, 208, 0) ,
174 HDD5GHZCHAN(5060, 212, 0) ,
175 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700176 HDD5GHZCHAN(5180, 36, 0) ,
177 HDD5GHZCHAN(5200, 40, 0) ,
178 HDD5GHZCHAN(5220, 44, 0) ,
179 HDD5GHZCHAN(5240, 48, 0) ,
180 HDD5GHZCHAN(5260, 52, 0) ,
181 HDD5GHZCHAN(5280, 56, 0) ,
182 HDD5GHZCHAN(5300, 60, 0) ,
183 HDD5GHZCHAN(5320, 64, 0) ,
184 HDD5GHZCHAN(5500,100, 0) ,
185 HDD5GHZCHAN(5520,104, 0) ,
186 HDD5GHZCHAN(5540,108, 0) ,
187 HDD5GHZCHAN(5560,112, 0) ,
188 HDD5GHZCHAN(5580,116, 0) ,
189 HDD5GHZCHAN(5600,120, 0) ,
190 HDD5GHZCHAN(5620,124, 0) ,
191 HDD5GHZCHAN(5640,128, 0) ,
192 HDD5GHZCHAN(5660,132, 0) ,
193 HDD5GHZCHAN(5680,136, 0) ,
194 HDD5GHZCHAN(5700,140, 0) ,
195 HDD5GHZCHAN(5745,149, 0) ,
196 HDD5GHZCHAN(5765,153, 0) ,
197 HDD5GHZCHAN(5785,157, 0) ,
198 HDD5GHZCHAN(5805,161, 0) ,
199 HDD5GHZCHAN(5825,165, 0) ,
200};
201
202static struct ieee80211_rate g_mode_rates[] =
203{
204 HDD_G_MODE_RATETAB(10, 0x1, 0),
205 HDD_G_MODE_RATETAB(20, 0x2, 0),
206 HDD_G_MODE_RATETAB(55, 0x4, 0),
207 HDD_G_MODE_RATETAB(110, 0x8, 0),
208 HDD_G_MODE_RATETAB(60, 0x10, 0),
209 HDD_G_MODE_RATETAB(90, 0x20, 0),
210 HDD_G_MODE_RATETAB(120, 0x40, 0),
211 HDD_G_MODE_RATETAB(180, 0x80, 0),
212 HDD_G_MODE_RATETAB(240, 0x100, 0),
213 HDD_G_MODE_RATETAB(360, 0x200, 0),
214 HDD_G_MODE_RATETAB(480, 0x400, 0),
215 HDD_G_MODE_RATETAB(540, 0x800, 0),
216};
217
218static struct ieee80211_rate a_mode_rates[] =
219{
220 HDD_G_MODE_RATETAB(60, 0x10, 0),
221 HDD_G_MODE_RATETAB(90, 0x20, 0),
222 HDD_G_MODE_RATETAB(120, 0x40, 0),
223 HDD_G_MODE_RATETAB(180, 0x80, 0),
224 HDD_G_MODE_RATETAB(240, 0x100, 0),
225 HDD_G_MODE_RATETAB(360, 0x200, 0),
226 HDD_G_MODE_RATETAB(480, 0x400, 0),
227 HDD_G_MODE_RATETAB(540, 0x800, 0),
228};
229
230static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
231{
232 .channels = hdd_channels_2_4_GHZ,
233 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
234 .band = IEEE80211_BAND_2GHZ,
235 .bitrates = g_mode_rates,
236 .n_bitrates = g_mode_rates_size,
237 .ht_cap.ht_supported = 1,
238 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
239 | IEEE80211_HT_CAP_GRN_FLD
240 | IEEE80211_HT_CAP_DSSSCCK40
241 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
242 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
243 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
244 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
245 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
246 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
247};
248
249#ifdef WLAN_FEATURE_P2P
250static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
251{
252 .channels = hdd_social_channels_2_4_GHZ,
253 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
254 .band = IEEE80211_BAND_2GHZ,
255 .bitrates = g_mode_rates,
256 .n_bitrates = g_mode_rates_size,
257 .ht_cap.ht_supported = 1,
258 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
259 | IEEE80211_HT_CAP_GRN_FLD
260 | IEEE80211_HT_CAP_DSSSCCK40
261 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
262 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
263 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
264 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
265 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
266 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
267};
268#endif
269
270static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
271{
272 .channels = hdd_channels_5_GHZ,
273 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
274 .band = IEEE80211_BAND_5GHZ,
275 .bitrates = a_mode_rates,
276 .n_bitrates = a_mode_rates_size,
277 .ht_cap.ht_supported = 1,
278 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
279 | IEEE80211_HT_CAP_GRN_FLD
280 | IEEE80211_HT_CAP_DSSSCCK40
281 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
282 | IEEE80211_HT_CAP_SGI_40
283 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
284 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
285 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
286 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
287 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
288 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
289};
290
291/* This structure contain information what kind of frame are expected in
292 TX/RX direction for each kind of interface */
293static const struct ieee80211_txrx_stypes
294wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
295 [NL80211_IFTYPE_STATION] = {
296 .tx = 0xffff,
297 .rx = BIT(SIR_MAC_MGMT_ACTION) |
298 BIT(SIR_MAC_MGMT_PROBE_REQ),
299 },
300 [NL80211_IFTYPE_AP] = {
301 .tx = 0xffff,
302 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
303 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
304 BIT(SIR_MAC_MGMT_PROBE_REQ) |
305 BIT(SIR_MAC_MGMT_DISASSOC) |
306 BIT(SIR_MAC_MGMT_AUTH) |
307 BIT(SIR_MAC_MGMT_DEAUTH) |
308 BIT(SIR_MAC_MGMT_ACTION),
309 },
310#ifdef WLAN_FEATURE_P2P
311 [NL80211_IFTYPE_P2P_CLIENT] = {
312 .tx = 0xffff,
313 .rx = BIT(SIR_MAC_MGMT_ACTION) |
314 BIT(SIR_MAC_MGMT_PROBE_REQ),
315 },
316 [NL80211_IFTYPE_P2P_GO] = {
317 /* This is also same as for SoftAP */
318 .tx = 0xffff,
319 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
320 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
321 BIT(SIR_MAC_MGMT_PROBE_REQ) |
322 BIT(SIR_MAC_MGMT_DISASSOC) |
323 BIT(SIR_MAC_MGMT_AUTH) |
324 BIT(SIR_MAC_MGMT_DEAUTH) |
325 BIT(SIR_MAC_MGMT_ACTION),
326 },
327#endif
328};
329
330static struct cfg80211_ops wlan_hdd_cfg80211_ops;
331
332/* Data rate 100KBPS based on IE Index */
333struct index_data_rate_type
334{
335 v_U8_t beacon_rate_index;
336 v_U16_t supported_rate[4];
337};
338
339/* 11B, 11G Rate table include Basic rate and Extended rate
340 The IDX field is the rate index
341 The HI field is the rate when RSSI is strong or being ignored
342 (in this case we report actual rate)
343 The MID field is the rate when RSSI is moderate
344 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
345 The LO field is the rate when RSSI is low
346 (in this case we don't report rates, actual current rate used)
347 */
348static const struct
349{
350 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700351 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700352} supported_data_rate[] =
353{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700354/* IDX HI HM LM LO (RSSI-based index */
355 {2, { 10, 10, 10, 0}},
356 {4, { 20, 20, 10, 0}},
357 {11, { 55, 20, 10, 0}},
358 {12, { 60, 55, 20, 0}},
359 {18, { 90, 55, 20, 0}},
360 {22, {110, 55, 20, 0}},
361 {24, {120, 90, 60, 0}},
362 {36, {180, 120, 60, 0}},
363 {44, {220, 180, 60, 0}},
364 {48, {240, 180, 90, 0}},
365 {66, {330, 180, 90, 0}},
366 {72, {360, 240, 90, 0}},
367 {96, {480, 240, 120, 0}},
368 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700369};
370
371/* MCS Based rate table */
372static struct index_data_rate_type supported_mcs_rate[] =
373{
374/* MCS L20 L40 S20 S40 */
375 {0, {65, 135, 72, 150}},
376 {1, {130, 270, 144, 300}},
377 {2, {195, 405, 217, 450}},
378 {3, {260, 540, 289, 600}},
379 {4, {390, 810, 433, 900}},
380 {5, {520, 1080, 578, 1200}},
381 {6, {585, 1215, 650, 1350}},
382 {7, {650, 1350, 722, 1500}}
383};
384
385extern struct net_device_ops net_ops_struct;
386
387/*
388 * FUNCTION: wlan_hdd_cfg80211_init
389 * This function is called by hdd_wlan_startup()
390 * during initialization.
391 * This function is used to initialize and register wiphy structure.
392 */
393struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
394{
395 struct wiphy *wiphy;
396 ENTER();
397
398 /*
399 * Create wiphy device
400 */
401 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
402
403 if (!wiphy)
404 {
405 /* Print error and jump into err label and free the memory */
406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
407 return NULL;
408 }
409
410 return wiphy;
411}
412
413/*
414 * FUNCTION: wlan_hdd_cfg80211_update_band
415 * This function is called from the supplicant through a
416 * private ioctl to change the band value
417 */
418int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
419{
Jeff Johnsone7245742012-09-05 17:12:55 -0700420 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700421 switch(eBand)
422 {
423 case eCSR_BAND_24:
424 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
425 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
426 break;
427 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700428#ifdef WLAN_FEATURE_P2P
429 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
430#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700431 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700432#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
434 break;
435 case eCSR_BAND_ALL:
436 default:
437 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
438 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
439 }
440 return 0;
441}
442/*
443 * FUNCTION: wlan_hdd_cfg80211_init
444 * This function is called by hdd_wlan_startup()
445 * during initialization.
446 * This function is used to initialize and register wiphy structure.
447 */
448int wlan_hdd_cfg80211_register(struct device *dev,
449 struct wiphy *wiphy,
450 hdd_config_t *pCfg
451 )
452{
Jeff Johnsone7245742012-09-05 17:12:55 -0700453 ENTER();
454
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 /* Now bind the underlying wlan device with wiphy */
456 set_wiphy_dev(wiphy, dev);
457
458 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
459
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700460 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700461
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700463 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
464 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
465 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700466 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700467#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700468 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
469 driver can still register regulatory callback and
470 it will get CRDA setting in wiphy->band[], but
471 driver need to determine what to do with both
472 regulatory settings */
473 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700474
Jeff Johnson295189b2012-06-20 16:38:30 -0700475 wiphy->max_scan_ssids = MAX_SCAN_SSID;
476
477 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
478
479 /* Supports STATION & AD-HOC modes right now */
480 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
481 | BIT(NL80211_IFTYPE_ADHOC)
482#ifdef WLAN_FEATURE_P2P
483 | BIT(NL80211_IFTYPE_P2P_CLIENT)
484 | BIT(NL80211_IFTYPE_P2P_GO)
485#endif
486 | BIT(NL80211_IFTYPE_AP);
487
488 /* Before registering we need to update the ht capabilitied based
489 * on ini values*/
490 if( !pCfg->ShortGI20MhzEnable )
491 {
492 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
493 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
494 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
495 }
496
497 if( !pCfg->ShortGI40MhzEnable )
498 {
499 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
500 }
501
502 if( !pCfg->nChannelBondingMode5GHz )
503 {
504 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
505 }
506
507 /*Initialize band capability*/
508 switch(pCfg->nBandCapability)
509 {
510 case eCSR_BAND_24:
511 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
512 break;
513 case eCSR_BAND_5G:
514#ifdef WLAN_FEATURE_P2P
515 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
516#endif
517 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
518 break;
519 case eCSR_BAND_ALL:
520 default:
521 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
522 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
523 }
524 /*Initialise the supported cipher suite details*/
525 wiphy->cipher_suites = hdd_cipher_suites;
526 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
527
528 /*signal strength in mBm (100*dBm) */
529 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
530
531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
532#ifdef WLAN_FEATURE_P2P
533 wiphy->max_remain_on_channel_duration = 1000;
534#endif
535#endif
536
537 /* Register our wiphy dev with cfg80211 */
538 if (0 > wiphy_register(wiphy))
539 {
540 /* print eror */
541 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
542 return -EIO;
543 }
544
545 EXIT();
546 return 0;
547}
548
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700549/* In this function we will try to get default country code from crda.
550 If the gCrdaDefaultCountryCode is configured in ini file,
551 we will try to call user space crda to get the regulatory settings for
552 that country. We will timeout if we can't get it from crda.
553 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
554*/
555int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
556{
557 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
558 if (memcmp(pCfg->crdaDefaultCountryCode,
559 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
560 {
561 init_completion(&pHddCtx->driver_crda_req);
562 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
563 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
564 CRDA_WAIT_TIME);
565 }
566 return 0;
567}
568
Jeff Johnson295189b2012-06-20 16:38:30 -0700569/* In this function we will do all post VOS start initialization.
570 In this function we will register for all frame in which supplicant
571 is interested.
572*/
573void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
574{
575#ifdef WLAN_FEATURE_P2P
576 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
577 /* Register for all P2P action, public action etc frames */
578 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
579
Jeff Johnsone7245742012-09-05 17:12:55 -0700580 ENTER();
581
Jeff Johnson295189b2012-06-20 16:38:30 -0700582 /* Right now we are registering these frame when driver is getting
583 initialized. Once we will move to 2.6.37 kernel, in which we have
584 frame register ops, we will move this code as a part of that */
585 /* GAS Initial Request */
586 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
587 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
588
589 /* GAS Initial Response */
590 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
591 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
592
593 /* GAS Comeback Request */
594 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
595 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
596
597 /* GAS Comeback Response */
598 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
599 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
600
601 /* P2P Public Action */
602 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
603 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
604 P2P_PUBLIC_ACTION_FRAME_SIZE );
605
606 /* P2P Action */
607 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
608 (v_U8_t*)P2P_ACTION_FRAME,
609 P2P_ACTION_FRAME_SIZE );
610#endif /* WLAN_FEATURE_P2P */
611}
612
613void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
614{
615#ifdef WLAN_FEATURE_P2P
616 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
617 /* Register for all P2P action, public action etc frames */
618 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
619
Jeff Johnsone7245742012-09-05 17:12:55 -0700620 ENTER();
621
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 /* Right now we are registering these frame when driver is getting
623 initialized. Once we will move to 2.6.37 kernel, in which we have
624 frame register ops, we will move this code as a part of that */
625 /* GAS Initial Request */
626
627 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
628 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
629
630 /* GAS Initial Response */
631 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
632 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
633
634 /* GAS Comeback Request */
635 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
636 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
637
638 /* GAS Comeback Response */
639 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
640 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
641
642 /* P2P Public Action */
643 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
644 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
645 P2P_PUBLIC_ACTION_FRAME_SIZE );
646
647 /* P2P Action */
648 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
649 (v_U8_t*)P2P_ACTION_FRAME,
650 P2P_ACTION_FRAME_SIZE );
651#endif /* WLAN_FEATURE_P2P */
652}
653
654#ifdef FEATURE_WLAN_WAPI
655void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
656 const u8 *mac_addr, u8 *key , int key_Len)
657{
658 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
659 tCsrRoamSetKey setKey;
660 v_BOOL_t isConnected = TRUE;
661 int status = 0;
662 v_U32_t roamId= 0xFF;
663 tANI_U8 *pKeyPtr = NULL;
664 int n = 0;
665
666 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
667 __func__,pAdapter->device_mode);
668
669 setKey.keyId = key_index; // Store Key ID
670 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
671 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
672 setKey.paeRole = 0 ; // the PAE role
673 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
674 {
675 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
676 }
677 else
678 {
679 isConnected = hdd_connIsConnected(pHddStaCtx);
680 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
681 }
682 setKey.keyLength = key_Len;
683 pKeyPtr = setKey.Key;
684 memcpy( pKeyPtr, key, key_Len);
685
686 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
687 __func__, key_Len);
688 for (n = 0 ; n < key_Len; n++)
689 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
690 __func__,n,setKey.Key[n]);
691
692 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
693 if ( isConnected )
694 {
695 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
696 pAdapter->sessionId, &setKey, &roamId );
697 }
698 if ( status != 0 )
699 {
700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
701 "[%4d] sme_RoamSetKey returned ERROR status= %d",
702 __LINE__, status );
703 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
704 }
705}
706#endif /* FEATURE_WLAN_WAPI*/
707
708#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
709int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
710 beacon_data_t **ppBeacon,
711 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700712#else
713int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
714 beacon_data_t **ppBeacon,
715 struct cfg80211_beacon_data *params,
716 int dtim_period)
717#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700718{
719 int size;
720 beacon_data_t *beacon = NULL;
721 beacon_data_t *old = NULL;
722 int head_len,tail_len;
723
Jeff Johnsone7245742012-09-05 17:12:55 -0700724 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 if (params->head && !params->head_len)
726 return -EINVAL;
727
728 old = pAdapter->sessionCtx.ap.beacon;
729
730 if (!params->head && !old)
731 return -EINVAL;
732
733 if (params->tail && !params->tail_len)
734 return -EINVAL;
735
736#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
737 /* Kernel 3.0 is not updating dtim_period for set beacon */
738 if (!params->dtim_period)
739 return -EINVAL;
740#endif
741
742 if(params->head)
743 head_len = params->head_len;
744 else
745 head_len = old->head_len;
746
747 if(params->tail || !old)
748 tail_len = params->tail_len;
749 else
750 tail_len = old->tail_len;
751
752 size = sizeof(beacon_data_t) + head_len + tail_len;
753
754 beacon = kzalloc(size, GFP_KERNEL);
755
756 if( beacon == NULL )
757 return -ENOMEM;
758
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700759#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700760 if(params->dtim_period || !old )
761 beacon->dtim_period = params->dtim_period;
762 else
763 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700764#else
765 if(dtim_period || !old )
766 beacon->dtim_period = dtim_period;
767 else
768 beacon->dtim_period = old->dtim_period;
769#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700770
771 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
772 beacon->tail = beacon->head + head_len;
773 beacon->head_len = head_len;
774 beacon->tail_len = tail_len;
775
776 if(params->head) {
777 memcpy (beacon->head,params->head,beacon->head_len);
778 }
779 else {
780 if(old)
781 memcpy (beacon->head,old->head,beacon->head_len);
782 }
783
784 if(params->tail) {
785 memcpy (beacon->tail,params->tail,beacon->tail_len);
786 }
787 else {
788 if(old)
789 memcpy (beacon->tail,old->tail,beacon->tail_len);
790 }
791
792 *ppBeacon = beacon;
793
794 kfree(old);
795
796 return 0;
797
798}
Jeff Johnson295189b2012-06-20 16:38:30 -0700799
800v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
801{
802 int left = length;
803 v_U8_t *ptr = pIes;
804 v_U8_t elem_id,elem_len;
805
806 while(left >= 2)
807 {
808 elem_id = ptr[0];
809 elem_len = ptr[1];
810 left -= 2;
811 if(elem_len > left)
812 {
813 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700814 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700815 eid,elem_len,left);
816 return NULL;
817 }
818 if (elem_id == eid)
819 {
820 return ptr;
821 }
822
823 left -= elem_len;
824 ptr += (elem_len + 2);
825 }
826 return NULL;
827}
828
Jeff Johnson295189b2012-06-20 16:38:30 -0700829/* Check if rate is 11g rate or not */
830static int wlan_hdd_rate_is_11g(u8 rate)
831{
832 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
833 u8 i;
834 for (i = 0; i < 8; i++)
835 {
836 if(rate == gRateArray[i])
837 return TRUE;
838 }
839 return FALSE;
840}
841
842/* Check for 11g rate and set proper 11g only mode */
843static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
844 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
845{
846 u8 i, num_rates = pIe[0];
847
848 pIe += 1;
849 for ( i = 0; i < num_rates; i++)
850 {
851 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
852 {
853 /* If rate set have 11g rate than change the mode to 11G */
854 *pSapHw_mode = eSAP_DOT11_MODE_11g;
855 if (pIe[i] & BASIC_RATE_MASK)
856 {
857 /* If we have 11g rate as basic rate, it means mode
858 is 11g only mode.
859 */
860 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
861 *pCheckRatesfor11g = FALSE;
862 }
863 }
864 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
865 {
866 *require_ht = TRUE;
867 }
868 }
869 return;
870}
871
872static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
873{
874 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
875 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
876 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
877 u8 checkRatesfor11g = TRUE;
878 u8 require_ht = FALSE;
879 u8 *pIe=NULL;
880
881 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
882
883 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
884 pBeacon->head_len, WLAN_EID_SUPP_RATES);
885 if (pIe != NULL)
886 {
887 pIe += 1;
888 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
889 &pConfig->SapHw_mode);
890 }
891
892 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
893 WLAN_EID_EXT_SUPP_RATES);
894 if (pIe != NULL)
895 {
896
897 pIe += 1;
898 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
899 &pConfig->SapHw_mode);
900 }
901
902 if( pConfig->channel > 14 )
903 {
904 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
905 }
906
907 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
908 WLAN_EID_HT_CAPABILITY);
909
910 if(pIe)
911 {
912 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
913 if(require_ht)
914 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
915 }
916}
917
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700918#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700919static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
920 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700921#else
922static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
923 struct cfg80211_beacon_data *params)
924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700925{
926 v_U8_t *genie;
927 v_U8_t total_ielen = 0, ielen = 0;
928 v_U8_t *pIe = NULL;
929 v_U8_t addIE[1] = {0};
930 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -0700931 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700932
933 genie = vos_mem_malloc(MAX_GENIE_LEN);
934
935 if(genie == NULL) {
936
937 return -ENOMEM;
938 }
939
940 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
941
942 if(pIe)
943 {
944 /*Copy the wps IE*/
945 ielen = pIe[1] + 2;
946 if( ielen <=MAX_GENIE_LEN)
947 {
948 vos_mem_copy(genie, pIe, ielen);
949 }
950 else
951 {
952 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700953 ret = -EINVAL;
954 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 }
956 total_ielen = ielen;
957 }
958
959#ifdef WLAN_FEATURE_WFD
960 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
961
962 if(pIe)
963 {
964 ielen = pIe[1] + 2;
965 if(total_ielen + ielen <= MAX_GENIE_LEN) {
966 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
967 }
968 else {
969 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700970 ret = -EINVAL;
971 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 }
973 total_ielen += ielen;
974 }
975#endif
976
977#ifdef WLAN_FEATURE_P2P
978 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
979
980 if(pIe)
981 {
982 ielen = pIe[1] + 2;
983 if(total_ielen + ielen <= MAX_GENIE_LEN)
984 {
985 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
986 }
987 else
988 {
989 hddLog( VOS_TRACE_LEVEL_ERROR,
990 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700991 ret = -EINVAL;
992 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 }
994 total_ielen += ielen;
995 }
996#endif
997
998 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
999 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1000 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1001 {
1002 hddLog(LOGE,
1003 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001004 ret = -EINVAL;
1005 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 }
1007
1008 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1009 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1010 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1011 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1012 ==eHAL_STATUS_FAILURE)
1013 {
1014 hddLog(LOGE,
1015 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001016 ret = -EINVAL;
1017 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 }
1019
1020 // Added for ProResp IE
1021 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1022 {
1023 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1024 u8 probe_rsp_ie_len[3] = {0};
1025 u8 counter = 0;
1026 /* Check Probe Resp Length if it is greater then 255 then Store
1027 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1028 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1029 Store More then 255 bytes into One Variable.
1030 */
1031 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1032 {
1033 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1034 {
1035 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1036 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1037 }
1038 else
1039 {
1040 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1041 rem_probe_resp_ie_len = 0;
1042 }
1043 }
1044
1045 rem_probe_resp_ie_len = 0;
1046
1047 if (probe_rsp_ie_len[0] > 0)
1048 {
1049 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1050 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1051 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1052 probe_rsp_ie_len[0], NULL,
1053 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1054 {
1055 hddLog(LOGE,
1056 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001057 ret = -EINVAL;
1058 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 }
1060 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1061 }
1062
1063 if (probe_rsp_ie_len[1] > 0)
1064 {
1065 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1066 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1067 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1068 probe_rsp_ie_len[1], NULL,
1069 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1070 {
1071 hddLog(LOGE,
1072 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001073 ret = -EINVAL;
1074 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 }
1076 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1077 }
1078
1079 if (probe_rsp_ie_len[2] > 0)
1080 {
1081 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1082 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1083 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1084 probe_rsp_ie_len[2], NULL,
1085 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1086 {
1087 hddLog(LOGE,
1088 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001089 ret = -EINVAL;
1090 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 }
1092 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1093 }
1094
1095 if (probe_rsp_ie_len[1] == 0 )
1096 {
1097 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1098 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1099 eANI_BOOLEAN_FALSE) )
1100 {
1101 hddLog(LOGE,
1102 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1103 }
1104 }
1105
1106 if (probe_rsp_ie_len[2] == 0 )
1107 {
1108 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1109 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1110 eANI_BOOLEAN_FALSE) )
1111 {
1112 hddLog(LOGE,
1113 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1114 }
1115 }
1116
1117 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1118 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1119 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1120 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1121 == eHAL_STATUS_FAILURE)
1122 {
1123 hddLog(LOGE,
1124 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001125 ret = -EINVAL;
1126 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 }
1128 }
1129 else
1130 {
1131 // Reset WNI_CFG_PROBE_RSP Flags
1132 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1133
1134 hddLog(VOS_TRACE_LEVEL_INFO,
1135 "%s: No Probe Response IE received in set beacon",
1136 __func__);
1137 }
1138
1139 // Added for AssocResp IE
1140 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1141 {
1142 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1143 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1144 params->assocresp_ies_len, NULL,
1145 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1146 {
1147 hddLog(LOGE,
1148 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001149 ret = -EINVAL;
1150 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001151 }
1152
1153 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1154 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1155 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1156 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1157 == eHAL_STATUS_FAILURE)
1158 {
1159 hddLog(LOGE,
1160 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001161 ret = -EINVAL;
1162 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 }
1164 }
1165 else
1166 {
1167 hddLog(VOS_TRACE_LEVEL_INFO,
1168 "%s: No Assoc Response IE received in set beacon",
1169 __func__);
1170
1171 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1172 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1173 eANI_BOOLEAN_FALSE) )
1174 {
1175 hddLog(LOGE,
1176 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1177 }
1178 }
1179
Jeff Johnsone7245742012-09-05 17:12:55 -07001180done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 vos_mem_free(genie);
1182 return 0;
1183}
Jeff Johnson295189b2012-06-20 16:38:30 -07001184
1185/*
1186 * FUNCTION: wlan_hdd_validate_operation_channel
1187 * called by wlan_hdd_cfg80211_start_bss() and
1188 * wlan_hdd_cfg80211_set_channel()
1189 * This function validates whether given channel is part of valid
1190 * channel list.
1191 */
1192static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1193{
1194
1195 v_U32_t num_ch = 0;
1196 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1197 u32 indx = 0;
1198 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1199
1200 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1201
1202 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1203 valid_ch, &num_ch))
1204 {
1205 hddLog(VOS_TRACE_LEVEL_ERROR,
1206 "%s: failed to get valid channel list\n", __func__);
1207 return VOS_STATUS_E_FAILURE;
1208 }
1209
1210 for (indx = 0; indx < num_ch; indx++)
1211 {
1212 if (channel == valid_ch[indx])
1213 {
1214 break;
1215 }
1216 }
1217
1218 if (indx >= num_ch)
1219 {
1220 hddLog(VOS_TRACE_LEVEL_ERROR,
1221 "%s: Invalid Channel [%d] \n", __func__, channel);
1222 return VOS_STATUS_E_FAILURE;
1223 }
1224 return VOS_STATUS_SUCCESS;
1225
1226}
1227
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001228
Jeff Johnson295189b2012-06-20 16:38:30 -07001229#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1230static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1231 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001232#else
1233static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1234 struct cfg80211_beacon_data *params,
1235 const u8 *ssid, size_t ssid_len,
1236 enum nl80211_hidden_ssid hidden_ssid)
1237#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001238{
Pratik Bhalgat8cc971c2012-11-22 17:36:14 +05301239 hdd_config_t *pConfigIni = ((hdd_context_t *)(pHostapdAdapter->pHddCtx))->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 tsap_Config_t *pConfig;
1241 beacon_data_t *pBeacon = NULL;
1242 struct ieee80211_mgmt *pMgmt_frame;
1243 v_U8_t *pIe=NULL;
1244 v_U16_t capab_info;
1245 eCsrAuthType RSNAuthType;
1246 eCsrEncryptionType RSNEncryptType;
1247 eCsrEncryptionType mcRSNEncryptType;
1248 int status = VOS_STATUS_SUCCESS;
1249 tpWLAN_SAPEventCB pSapEventCallback;
1250 hdd_hostapd_state_t *pHostapdState;
1251 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1252 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1253 struct qc_mac_acl_entry *acl_entry = NULL;
1254 v_SINT_t i;
1255
1256 ENTER();
1257
1258 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1259
1260 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1261
1262 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1263
1264 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1265
1266 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1267
1268 //channel is already set in the set_channel Call back
1269 //pConfig->channel = pCommitConfig->channel;
1270
1271 /*Protection parameter to enable or disable*/
1272 pConfig->protEnabled =
1273 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1274
1275 pConfig->dtim_period = pBeacon->dtim_period;
1276
1277 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1278 pConfig->dtim_period);
1279
1280
Pratik Bhalgat8cc971c2012-11-22 17:36:14 +05301281 /* Hdd cfg settings takes preference */
1282 if (pConfigIni->Is11dSupportEnabled && (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP))
Jeff Johnson32d95a32012-09-10 13:15:23 -07001283 {
1284 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001285 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001286 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001287 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001288 tANI_BOOLEAN restartNeeded;
1289 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1290 pConfig->ieee80211d = 1;
1291 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1292 sme_setRegInfo(hHal, pConfig->countryCode);
1293 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1294 /*
1295 * If auto channel is configured i.e. channel is 0,
1296 * so skip channel validation.
1297 */
1298 if( AUTO_CHANNEL_SELECT != pConfig->channel )
Jeff Johnson295189b2012-06-20 16:38:30 -07001299 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001300 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1301 {
1302 hddLog(VOS_TRACE_LEVEL_ERROR,
1303 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1304 return -EINVAL;
1305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001307 /*
1308 * Validate the given channel range for the given country code
1309 */
1310 else
1311 {
1312 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1313 WLANSAP_SetChannelRange(hHal,hdd_pConfig->apStartChannelNum,hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1314 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001316 else
1317 {
1318 pConfig->ieee80211d = 0;
1319 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001320 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001321 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 {
1323 pConfig->ieee80211d = 0;
1324 }
1325 pConfig->authType = eSAP_AUTO_SWITCH;
1326
1327 capab_info = pMgmt_frame->u.beacon.capab_info;
1328
1329 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1330 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1331
1332 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1333
1334 /*Set wps station to configured*/
1335 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1336
1337 if(pIe)
1338 {
1339 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1340 {
1341 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1342 return -EINVAL;
1343 }
1344 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1345 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001346 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 /* Check 15 bit of WPS IE as it contain information for wps state
1348 * WPS state
1349 */
1350 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1351 {
1352 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1353 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1354 {
1355 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1356 }
1357 }
1358 }
1359 else
1360 {
1361 pConfig->wps_state = SAP_WPS_DISABLED;
1362 }
1363 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1364
1365 pConfig->RSNWPAReqIELength = 0;
1366 pConfig->pRSNWPAReqIE = NULL;
1367 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1368 WLAN_EID_RSN);
1369 if(pIe && pIe[1])
1370 {
1371 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1372 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1373 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1374 /* The actual processing may eventually be more extensive than
1375 * this. Right now, just consume any PMKIDs that are sent in
1376 * by the app.
1377 * */
1378 status = hdd_softap_unpackIE(
1379 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1380 &RSNEncryptType,
1381 &mcRSNEncryptType,
1382 &RSNAuthType,
1383 pConfig->pRSNWPAReqIE[1]+2,
1384 pConfig->pRSNWPAReqIE );
1385
1386 if( VOS_STATUS_SUCCESS == status )
1387 {
1388 /* Now copy over all the security attributes you have
1389 * parsed out
1390 * */
1391 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1392 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1393 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1394 = RSNEncryptType;
1395 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1396 "EncryptionType = %d mcEncryptionType = %d\n"),
1397 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1398 }
1399 }
1400
1401 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1402 pBeacon->tail, pBeacon->tail_len);
1403
1404 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1405 {
1406 if (pConfig->pRSNWPAReqIE)
1407 {
1408 /*Mixed mode WPA/WPA2*/
1409 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1410 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1411 }
1412 else
1413 {
1414 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1415 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1416 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1417 status = hdd_softap_unpackIE(
1418 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1419 &RSNEncryptType,
1420 &mcRSNEncryptType,
1421 &RSNAuthType,
1422 pConfig->pRSNWPAReqIE[1]+2,
1423 pConfig->pRSNWPAReqIE );
1424
1425 if( VOS_STATUS_SUCCESS == status )
1426 {
1427 /* Now copy over all the security attributes you have
1428 * parsed out
1429 * */
1430 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1431 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1432 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1433 = RSNEncryptType;
1434 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1435 "EncryptionType = %d mcEncryptionType = %d\n"),
1436 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1437 }
1438 }
1439 }
1440
1441 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1442
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001443#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001444 if (params->ssid != NULL)
1445 {
1446 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1447 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1448 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1449 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1450 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001451#else
1452 if (ssid != NULL)
1453 {
1454 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1455 pConfig->SSIDinfo.ssid.length = ssid_len;
1456 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1457 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1458 }
1459#endif
1460
Jeff Johnson295189b2012-06-20 16:38:30 -07001461 vos_mem_copy(pConfig->self_macaddr.bytes,
1462 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1463
1464 /* default value */
1465 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1466 pConfig->num_accept_mac = 0;
1467 pConfig->num_deny_mac = 0;
1468
1469 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1470 pBeacon->tail, pBeacon->tail_len);
1471
1472 /* pIe for black list is following form:
1473 type : 1 byte
1474 length : 1 byte
1475 OUI : 4 bytes
1476 acl type : 1 byte
1477 no of mac addr in black list: 1 byte
1478 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1479 */
1480 if ((pIe != NULL) && (pIe[1] != 0))
1481 {
1482 pConfig->SapMacaddr_acl = pIe[6];
1483 pConfig->num_deny_mac = pIe[7];
1484 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1485 pIe[6], pIe[7]);
1486 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1487 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1488 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1489 for (i = 0; i < pConfig->num_deny_mac; i++)
1490 {
1491 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1492 acl_entry++;
1493 }
1494 }
1495 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1496 pBeacon->tail, pBeacon->tail_len);
1497
1498 /* pIe for white list is following form:
1499 type : 1 byte
1500 length : 1 byte
1501 OUI : 4 bytes
1502 acl type : 1 byte
1503 no of mac addr in white list: 1 byte
1504 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1505 */
1506 if ((pIe != NULL) && (pIe[1] != 0))
1507 {
1508 pConfig->SapMacaddr_acl = pIe[6];
1509 pConfig->num_accept_mac = pIe[7];
1510 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1511 pIe[6], pIe[7]);
1512 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1513 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1514 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1515 for (i = 0; i < pConfig->num_accept_mac; i++)
1516 {
1517 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1518 acl_entry++;
1519 }
1520 }
1521 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1522
Jeff Johnsone7245742012-09-05 17:12:55 -07001523#ifdef WLAN_FEATURE_11AC
1524 if(((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1525 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1526 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) )
1527 {
1528 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1529 }
1530#endif
1531
Jeff Johnson295189b2012-06-20 16:38:30 -07001532 // ht_capab is not what the name conveys,this is used for protection bitmap
1533 pConfig->ht_capab =
1534 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1535
1536 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1537 {
1538 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1539 return -EINVAL;
1540 }
1541
1542 //Uapsd Enabled Bit
1543 pConfig->UapsdEnable =
1544 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1545 //Enable OBSS protection
1546 pConfig->obssProtEnabled =
1547 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1548
1549 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1550 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1551 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1552 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1553 (int)pConfig->channel);
1554 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1555 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1556 pConfig->authType);
1557 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1558 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1559 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1560 pConfig->protEnabled, pConfig->obssProtEnabled);
1561
1562 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1563 {
1564 //Bss already started. just return.
1565 //TODO Probably it should update some beacon params.
1566 hddLog( LOGE, "Bss Already started...Ignore the request");
1567 EXIT();
1568 return 0;
1569 }
1570
1571 pConfig->persona = pHostapdAdapter->device_mode;
1572
1573 pSapEventCallback = hdd_hostapd_SAPEventCB;
1574 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1575 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1576 {
1577 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1578 return -EINVAL;
1579 }
1580
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001581 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1583
1584 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1585
1586 if (!VOS_IS_STATUS_SUCCESS(status))
1587 {
1588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1589 ("ERROR: HDD vos wait for single_event failed!!\n"));
1590 VOS_ASSERT(0);
1591 }
1592
1593 //Succesfully started Bss update the state bit.
1594 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1595
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001596#ifdef WLAN_FEATURE_P2P_DEBUG
1597 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1598 {
1599 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1600 {
1601 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1602 hddLog(LOGE,"[P2P State] From Go nego completed to "
1603 "Non-autonomus Group started");
1604 }
1605 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1606 {
1607 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1608 hddLog(LOGE,"[P2P State] From Inactive to "
1609 "Autonomus Group started");
1610 }
1611 }
1612#endif
1613
Jeff Johnson295189b2012-06-20 16:38:30 -07001614 pHostapdState->bCommit = TRUE;
1615 EXIT();
1616
1617 return 0;
1618}
1619
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001620#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001621static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1622 struct net_device *dev,
1623 struct beacon_parameters *params)
1624{
1625 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1626 int status=VOS_STATUS_SUCCESS;
1627
1628 ENTER();
1629
1630 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1631
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001632 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1633 {
1634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1635 "%s:LOGP in Progress. Ignore!!!", __func__);
1636 return -EAGAIN;
1637 }
1638
Jeff Johnson295189b2012-06-20 16:38:30 -07001639 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1640#ifdef WLAN_FEATURE_P2P
1641 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1642#endif
1643 )
1644 {
1645 beacon_data_t *old,*new;
1646
1647 old = pAdapter->sessionCtx.ap.beacon;
1648
1649 if (old)
1650 return -EALREADY;
1651
1652 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1653
1654 if(status != VOS_STATUS_SUCCESS)
1655 {
1656 hddLog(VOS_TRACE_LEVEL_FATAL,
1657 "%s:Error!!! Allocating the new beacon\n",__func__);
1658 return -EINVAL;
1659 }
1660
1661 pAdapter->sessionCtx.ap.beacon = new;
1662
1663 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1664 }
1665
1666 EXIT();
1667 return status;
1668}
1669
1670static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
1671 struct net_device *dev,
1672 struct beacon_parameters *params)
1673{
1674 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1675 int status=VOS_STATUS_SUCCESS;
1676
1677 ENTER();
1678
1679 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1680 __func__,pAdapter->device_mode);
1681
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001682 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1683 {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1685 "%s:LOGP in Progress. Ignore!!!", __func__);
1686 return -EAGAIN;
1687 }
1688
Jeff Johnson295189b2012-06-20 16:38:30 -07001689 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1690#ifdef WLAN_FEATURE_P2P
1691 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1692#endif
1693 )
1694 {
1695 beacon_data_t *old,*new;
1696
1697 old = pAdapter->sessionCtx.ap.beacon;
1698
1699 if (!old)
1700 return -ENOENT;
1701
1702 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1703
1704 if(status != VOS_STATUS_SUCCESS) {
1705 hddLog(VOS_TRACE_LEVEL_FATAL,
1706 "%s: Error!!! Allocating the new beacon\n",__func__);
1707 return -EINVAL;
1708 }
1709
1710 pAdapter->sessionCtx.ap.beacon = new;
1711
1712 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1713 }
1714
1715 EXIT();
1716 return status;
1717}
1718
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001719#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1720
1721#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001722static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
1723 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001724#else
1725static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
1726 struct net_device *dev)
1727#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001728{
1729 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001730 hdd_context_t *pHddCtx = NULL;
1731 hdd_scaninfo_t *pScanInfo = NULL;
1732 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001733 VOS_STATUS status = 0;
1734
1735 ENTER();
1736
1737 if (NULL == pAdapter)
1738 {
1739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001740 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001741 return -ENODEV;
1742 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001743 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1744 {
1745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1746 "%s:LOGP in Progress. Ignore!!!", __func__);
1747 return -EAGAIN;
1748 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001749
1750 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1751 if (NULL == pHddCtx)
1752 {
1753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001754 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001755 return -ENODEV;
1756 }
1757
1758 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
1759 if (NULL == staAdapter)
1760 {
1761 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
1762 if (NULL == staAdapter)
1763 {
1764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001765 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001766 return -ENODEV;
1767 }
1768 }
1769
1770 pScanInfo = &pHddCtx->scan_info;
1771
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1773 {
1774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1775 return -EAGAIN;
1776 }
1777
1778 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1779
1780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1781 __func__,pAdapter->device_mode);
1782
Jeff Johnsone7245742012-09-05 17:12:55 -07001783 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
1784 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001785 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07001786 hdd_abort_mac_scan(staAdapter->pHddCtx);
1787 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001788 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07001789 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
1790 if (!status)
1791 {
1792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1793 "%s: Timeout occured while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001794 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001795 VOS_ASSERT(pScanInfo->mScanPending);
1796 return 0;
1797 }
1798 }
1799
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1801#ifdef WLAN_FEATURE_P2P
1802 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1803#endif
1804 )
1805 {
1806 beacon_data_t *old;
1807
1808 old = pAdapter->sessionCtx.ap.beacon;
1809
1810 if (!old)
1811 return -ENOENT;
1812
1813#ifdef CONFIG_CFG80211
1814 hdd_cleanup_actionframe(pHddCtx, pAdapter);
1815#endif
1816
1817 mutex_lock(&pHddCtx->sap_lock);
1818 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
1819 {
1820 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
1821 {
1822 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1823
1824 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1825
1826 if (!VOS_IS_STATUS_SUCCESS(status))
1827 {
1828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1829 ("ERROR: HDD vos wait for single_event failed!!\n"));
1830 VOS_ASSERT(0);
1831 }
1832 }
1833 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
1834 }
1835 mutex_unlock(&pHddCtx->sap_lock);
1836
1837 if(status != VOS_STATUS_SUCCESS)
1838 {
1839 hddLog(VOS_TRACE_LEVEL_FATAL,
1840 "%s:Error!!! Stopping the BSS\n",__func__);
1841 return -EINVAL;
1842 }
1843
1844 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1845 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
1846 ==eHAL_STATUS_FAILURE)
1847 {
1848 hddLog(LOGE,
1849 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
1850 }
1851
1852 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1853 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1854 eANI_BOOLEAN_FALSE) )
1855 {
1856 hddLog(LOGE,
1857 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1858 }
1859
1860 // Reset WNI_CFG_PROBE_RSP Flags
1861 wlan_hdd_reset_prob_rspies(pAdapter);
1862
1863 pAdapter->sessionCtx.ap.beacon = NULL;
1864 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001865#ifdef WLAN_FEATURE_P2P_DEBUG
1866 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
1867 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
1868 {
1869 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
1870 "GO got removed");
1871 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
1872 }
1873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001874 }
1875 EXIT();
1876 return status;
1877}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001878
1879#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
1880
1881static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
1882 struct net_device *dev,
1883 struct cfg80211_ap_settings *params)
1884{
1885 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1886 int status = VOS_STATUS_SUCCESS;
1887
1888 ENTER();
1889
1890 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n", pAdapter->device_mode);
1891
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001892 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1893 {
1894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1895 return -EAGAIN;
1896 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001897 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1898#ifdef WLAN_FEATURE_P2P
1899 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1900#endif
1901 )
1902 {
1903 beacon_data_t *old,*new;
1904
1905 old = pAdapter->sessionCtx.ap.beacon;
1906
1907 if (old)
1908 return -EALREADY;
1909
1910 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
1911
1912 if(status != VOS_STATUS_SUCCESS)
1913 {
1914 hddLog(VOS_TRACE_LEVEL_FATAL,
1915 "%s:Error!!! Allocating the new beacon\n",__func__);
1916 return -EINVAL;
1917 }
1918 pAdapter->sessionCtx.ap.beacon = new;
1919 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
1920 params->ssid_len, params->hidden_ssid);
1921 }
1922
1923 EXIT();
1924 return status;
1925}
1926
1927
1928static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
1929 struct net_device *dev,
1930 struct cfg80211_beacon_data *params)
1931{
1932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1933 int status=VOS_STATUS_SUCCESS;
1934
1935 ENTER();
1936
1937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1938 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001939 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1940 {
1941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1942 return -EAGAIN;
1943 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001944
1945 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1946#ifdef WLAN_FEATURE_P2P
1947 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1948#endif
1949 )
1950 {
1951 beacon_data_t *old,*new;
1952
1953 old = pAdapter->sessionCtx.ap.beacon;
1954
1955 if (!old)
1956 return -ENOENT;
1957
1958 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
1959
1960 if(status != VOS_STATUS_SUCCESS) {
1961 hddLog(VOS_TRACE_LEVEL_FATAL,
1962 "%s: Error!!! Allocating the new beacon\n",__func__);
1963 return -EINVAL;
1964 }
1965
1966 pAdapter->sessionCtx.ap.beacon = new;
1967
1968 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
1969 }
1970
1971 EXIT();
1972 return status;
1973}
1974
1975#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
1976
Jeff Johnson295189b2012-06-20 16:38:30 -07001977
1978static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
1979 struct net_device *dev,
1980 struct bss_parameters *params)
1981{
1982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1983
1984 ENTER();
1985
1986 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1987 __func__,pAdapter->device_mode);
1988
1989 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1990#ifdef WLAN_FEATURE_P2P
1991 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1992#endif
1993 )
1994 {
1995 /* ap_isolate == -1 means that in change bss, upper layer doesn't
1996 * want to update this parameter */
1997 if (-1 != params->ap_isolate)
1998 {
1999 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2000 }
2001 }
2002
2003 EXIT();
2004 return 0;
2005}
2006
2007/*
2008 * FUNCTION: wlan_hdd_cfg80211_change_iface
2009 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2010 */
2011int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2012 struct net_device *ndev,
2013 enum nl80211_iftype type,
2014 u32 *flags,
2015 struct vif_params *params
2016 )
2017{
2018 struct wireless_dev *wdev;
2019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2020 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002021 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 tCsrRoamProfile *pRoamProfile = NULL;
2023 eCsrRoamBssType LastBSSType;
2024 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2025 eMib_dot11DesiredBssType connectedBssType;
2026 VOS_STATUS status;
2027
2028 ENTER();
2029
2030 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2031 {
2032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2033 return -EAGAIN;
2034 }
2035
2036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2037 __func__, pAdapter->device_mode);
2038
2039 wdev = ndev->ieee80211_ptr;
2040
2041#ifdef WLAN_BTAMP_FEATURE
2042 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2043 (NL80211_IFTYPE_ADHOC == type)||
2044 (NL80211_IFTYPE_AP == type)||
2045 (NL80211_IFTYPE_P2P_GO == type))
2046 {
2047 pHddCtx->isAmpAllowed = VOS_FALSE;
2048 // stop AMP traffic
2049 status = WLANBAP_StopAmp();
2050 if(VOS_STATUS_SUCCESS != status )
2051 {
2052 pHddCtx->isAmpAllowed = VOS_TRUE;
2053 hddLog(VOS_TRACE_LEVEL_FATAL,
2054 "%s: Failed to stop AMP", __func__);
2055 return -EINVAL;
2056 }
2057 }
2058#endif //WLAN_BTAMP_FEATURE
2059 /* Reset the current device mode bit mask*/
2060 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2061
2062 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2063#ifdef WLAN_FEATURE_P2P
2064 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002065 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002066#endif
2067 )
2068 {
2069 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2070 pRoamProfile = &pWextState->roamProfile;
2071 LastBSSType = pRoamProfile->BSSType;
2072
2073 switch (type)
2074 {
2075 case NL80211_IFTYPE_STATION:
2076#ifdef WLAN_FEATURE_P2P
2077 case NL80211_IFTYPE_P2P_CLIENT:
2078#endif
2079 hddLog(VOS_TRACE_LEVEL_INFO,
2080 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2081 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002082#ifdef WLAN_FEATURE_11AC
2083 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2084 {
2085 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2086 }
2087#endif
2088 pRoamProfile->phyMode =
2089 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 wdev->iftype = type;
2091#ifdef WLAN_FEATURE_P2P
2092 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2093 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
2094#endif
2095 break;
2096 case NL80211_IFTYPE_ADHOC:
2097 hddLog(VOS_TRACE_LEVEL_INFO,
2098 "%s: setting interface Type to ADHOC", __func__);
2099 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2100 pRoamProfile->phyMode =
2101 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2102 wdev->iftype = type;
2103 break;
2104
2105 case NL80211_IFTYPE_AP:
2106#ifdef WLAN_FEATURE_P2P
2107 case NL80211_IFTYPE_P2P_GO:
2108#endif
2109 {
2110 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2111 "%s: setting interface Type to %s", __func__,
2112 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2113
Mohit Khanna0f232092012-09-11 14:46:08 -07002114 if (NL80211_IFTYPE_AP == type)
2115 {
2116 /* As Loading WLAN Driver one interface being created for p2p device
2117 * address. This will take one HW STA and the max number of clients
2118 * that can connect to softAP will be reduced by one. so while changing
2119 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2120 * interface as it is not required in SoftAP mode.
2121 */
2122
2123 // Get P2P Adapter
2124 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2125
2126 if (pP2pAdapter)
2127 {
2128 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2129 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2130 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2131 }
2132 }
2133
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 //De-init the adapter.
2135 hdd_stop_adapter( pHddCtx, pAdapter );
2136 hdd_deinit_adapter( pHddCtx, pAdapter );
2137 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2138#ifdef WLAN_SOFTAP_FEATURE
2139#ifdef WLAN_FEATURE_P2P
2140 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2141 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2142#else
2143 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2144#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002145
2146 //Disable BMPS and IMPS if enabled
2147 //before starting Go
2148 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2149 {
2150 if(VOS_STATUS_E_FAILURE ==
2151 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2152 {
2153 //Fail to Exit BMPS
2154 VOS_ASSERT(0);
2155 }
2156 }
2157
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002158 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2159 (pConfig->apRandomBssidEnabled))
2160 {
2161 /* To meet Android requirements create a randomized
2162 MAC address of the form 02:1A:11:Fx:xx:xx */
2163 get_random_bytes(&ndev->dev_addr[3], 3);
2164 ndev->dev_addr[0] = 0x02;
2165 ndev->dev_addr[1] = 0x1A;
2166 ndev->dev_addr[2] = 0x11;
2167 ndev->dev_addr[3] |= 0xF0;
2168 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2169 VOS_MAC_ADDR_SIZE);
2170 pr_info("wlan: Generated HotSpot BSSID "
2171 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2172 ndev->dev_addr[0],
2173 ndev->dev_addr[1],
2174 ndev->dev_addr[2],
2175 ndev->dev_addr[3],
2176 ndev->dev_addr[4],
2177 ndev->dev_addr[5]);
2178 }
2179
Jeff Johnson295189b2012-06-20 16:38:30 -07002180 hdd_set_ap_ops( pAdapter->dev );
2181
2182 status = hdd_init_ap_mode(pAdapter);
2183 if(status != VOS_STATUS_SUCCESS)
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,
2186 "%s: Error initializing the ap mode", __func__);
2187 return -EINVAL;
2188 }
2189 hdd_set_conparam(1);
2190
2191#endif
2192 /*interface type changed update in wiphy structure*/
2193 if(wdev)
2194 {
2195 wdev->iftype = type;
2196 pHddCtx->change_iface = type;
2197 }
2198 else
2199 {
2200 hddLog(VOS_TRACE_LEVEL_ERROR,
2201 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2202 return -EINVAL;
2203 }
2204 goto done;
2205 }
2206
2207 default:
2208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2209 __func__);
2210 return -EOPNOTSUPP;
2211 }
2212 }
2213 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2214#ifdef WLAN_FEATURE_P2P
2215 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2216#endif
2217 )
2218 {
2219 switch(type)
2220 {
2221 case NL80211_IFTYPE_STATION:
2222#ifdef WLAN_FEATURE_P2P
2223 case NL80211_IFTYPE_P2P_CLIENT:
2224#endif
2225 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002226 hdd_stop_adapter( pHddCtx, pAdapter );
2227 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 wdev->iftype = type;
2229#ifdef WLAN_FEATURE_P2P
2230 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2231 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
2232#endif
2233 hdd_set_conparam(0);
2234 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2236 hdd_set_station_ops( pAdapter->dev );
2237 status = hdd_init_station_mode( pAdapter );
2238 if( VOS_STATUS_SUCCESS != status )
2239 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002240 /* In case of JB, for P2P-GO, only change interface will be called,
2241 * This is the right place to enable back bmps_imps()
2242 */
2243 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 goto done;
2245 case NL80211_IFTYPE_AP:
2246#ifdef WLAN_FEATURE_P2P
2247 case NL80211_IFTYPE_P2P_GO:
2248#endif
2249 wdev->iftype = type;
2250#ifdef WLAN_FEATURE_P2P
2251 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2252 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2253#endif
2254 goto done;
2255 default:
2256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2257 __func__);
2258 return -EOPNOTSUPP;
2259
2260 }
2261
2262 }
2263 else
2264 {
2265 return -EOPNOTSUPP;
2266 }
2267
2268
2269 if(pRoamProfile)
2270 {
2271 if ( LastBSSType != pRoamProfile->BSSType )
2272 {
2273 /*interface type changed update in wiphy structure*/
2274 wdev->iftype = type;
2275
2276 /*the BSS mode changed, We need to issue disconnect
2277 if connected or in IBSS disconnect state*/
2278 if ( hdd_connGetConnectedBssType(
2279 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2280 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2281 {
2282 /*need to issue a disconnect to CSR.*/
2283 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2284 if( eHAL_STATUS_SUCCESS ==
2285 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2286 pAdapter->sessionId,
2287 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2288 {
2289 wait_for_completion_interruptible_timeout(
2290 &pAdapter->disconnect_comp_var,
2291 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2292 }
2293 }
2294 }
2295 }
2296
2297done:
2298 /*set bitmask based on updated value*/
2299 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2300#ifdef WLAN_BTAMP_FEATURE
2301 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2302 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2303 {
2304 //we are ok to do AMP
2305 pHddCtx->isAmpAllowed = VOS_TRUE;
2306 }
2307#endif //WLAN_BTAMP_FEATURE
2308 EXIT();
2309 return 0;
2310}
2311
2312static int wlan_hdd_change_station(struct wiphy *wiphy,
2313 struct net_device *dev,
2314 u8 *mac,
2315 struct station_parameters *params)
2316{
2317 VOS_STATUS status = VOS_STATUS_SUCCESS;
2318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2319 v_MACADDR_t STAMacAddress;
2320
Jeff Johnsone7245742012-09-05 17:12:55 -07002321 ENTER();
2322
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002323 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2324 {
2325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2326 "%s:LOGP in Progress. Ignore!!!", __func__);
2327 return -EAGAIN;
2328 }
2329
Jeff Johnson295189b2012-06-20 16:38:30 -07002330 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2331
2332 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2333#ifdef WLAN_FEATURE_P2P
2334 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2335#endif
2336 )
2337 {
2338 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2339 {
2340 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2341 WLANTL_STA_AUTHENTICATED);
2342
2343 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002344 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002345 return -EINVAL;
2346 }
2347 }
2348
Jeff Johnsone7245742012-09-05 17:12:55 -07002349 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002350 return status;
2351}
2352
2353/*
2354 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2355 * This function is used to get peer station index in IBSS mode
2356 */
2357static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2358{
2359 u8 idx = 0;
2360 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2361 ENTER();
2362 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2363 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2364 {
2365 if ( (0 !=
2366 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2367 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2368 temp, VOS_MAC_ADDR_SIZE)
2369 )
2370 {
2371 return idx;
2372 }
2373 }
2374 return idx;
2375}
2376
2377
2378/*
2379 * FUNCTION: wlan_hdd_cfg80211_add_key
2380 * This function is used to initialize the key information
2381 */
2382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2383static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2384 struct net_device *ndev,
2385 u8 key_index, bool pairwise,
2386 const u8 *mac_addr,
2387 struct key_params *params
2388 )
2389#else
2390static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2391 struct net_device *ndev,
2392 u8 key_index, const u8 *mac_addr,
2393 struct key_params *params
2394 )
2395#endif
2396{
2397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2398 tCsrRoamSetKey setKey;
2399 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2400 int status = 0;
2401 v_U32_t roamId= 0xFF;
2402 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2403 hdd_hostapd_state_t *pHostapdState;
2404 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002405 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002406
2407 ENTER();
2408
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002409 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2410 {
2411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2412 "%s:LOGP in Progress. Ignore!!!", __func__);
2413 return -EAGAIN;
2414 }
2415
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2417 __func__,pAdapter->device_mode);
2418
2419 if (CSR_MAX_NUM_KEY <= key_index)
2420 {
2421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2422 key_index);
2423
2424 return -EINVAL;
2425 }
2426
2427 hddLog(VOS_TRACE_LEVEL_INFO,
2428 "%s: called with key index = %d & key length %d",
2429 __func__, key_index, params->key_len);
2430
2431 /*extract key idx, key len and key*/
2432 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2433 setKey.keyId = key_index;
2434 setKey.keyLength = params->key_len;
2435 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2436
2437 switch (params->cipher)
2438 {
2439 case WLAN_CIPHER_SUITE_WEP40:
2440 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2441 break;
2442
2443 case WLAN_CIPHER_SUITE_WEP104:
2444 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2445 break;
2446
2447 case WLAN_CIPHER_SUITE_TKIP:
2448 {
2449 u8 *pKey = &setKey.Key[0];
2450 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2451
2452 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2453
2454 /*Supplicant sends the 32bytes key in this order
2455
2456 |--------------|----------|----------|
2457 | Tk1 |TX-MIC | RX Mic |
2458 |--------------|----------|----------|
2459 <---16bytes---><--8bytes--><--8bytes-->
2460
2461 */
2462 /*Sme expects the 32 bytes key to be in the below order
2463
2464 |--------------|----------|----------|
2465 | Tk1 |RX-MIC | TX Mic |
2466 |--------------|----------|----------|
2467 <---16bytes---><--8bytes--><--8bytes-->
2468 */
2469 /* Copy the Temporal Key 1 (TK1) */
2470 vos_mem_copy(pKey, params->key,16);
2471
2472 /*Copy the rx mic first*/
2473 vos_mem_copy(&pKey[16],&params->key[24],8);
2474
2475 /*Copy the tx mic */
2476 vos_mem_copy(&pKey[24],&params->key[16],8);
2477
2478
2479 break;
2480 }
2481
2482 case WLAN_CIPHER_SUITE_CCMP:
2483 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2484 break;
2485
2486#ifdef FEATURE_WLAN_WAPI
2487 case WLAN_CIPHER_SUITE_SMS4:
2488 {
2489 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2490 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2491 params->key, params->key_len);
2492 return 0;
2493 }
2494#endif
2495#ifdef FEATURE_WLAN_CCX
2496 case WLAN_CIPHER_SUITE_KRK:
2497 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2498 break;
2499#endif
2500 default:
2501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2502 __func__, params->cipher);
2503 return -EOPNOTSUPP;
2504 }
2505
2506 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2507 __func__, setKey.encType);
2508
2509
2510
2511 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2512#ifdef WLAN_FEATURE_P2P
2513 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2514#endif
2515 )
2516 {
2517
2518
2519 if (
2520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2521 (!pairwise)
2522#else
2523 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2524#endif
2525 )
2526 {
2527 /* set group key*/
2528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2529 "%s- %d: setting Broacast key",
2530 __func__, __LINE__);
2531 setKey.keyDirection = eSIR_RX_ONLY;
2532 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2533 }
2534 else
2535 {
2536 /* set pairwise key*/
2537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2538 "%s- %d: setting pairwise key",
2539 __func__, __LINE__);
2540 setKey.keyDirection = eSIR_TX_RX;
2541 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2542 }
2543
2544 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2545 if( pHostapdState->bssState == BSS_START )
2546 {
2547 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2548
2549 if ( status != eHAL_STATUS_SUCCESS )
2550 {
2551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2552 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2553 __LINE__, status );
2554 }
2555 }
2556
2557 /* Saving WEP keys */
2558 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2559 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2560 {
2561 //Save the wep key in ap context. Issue setkey after the BSS is started.
2562 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2563 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2564 }
2565 else
2566 {
2567 //Save the key in ap context. Issue setkey after the BSS is started.
2568 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2569 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2570 }
2571 }
2572 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2573#ifdef WLAN_FEATURE_P2P
2574 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2575#endif
2576 )
2577 {
2578 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2579 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2580
2581 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
2582
2583 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
2584 params->key, params->key_len);
2585
2586 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2587
2588 if (!( ( IW_AUTH_KEY_MGMT_802_1X
2589 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2590 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2591 )
2592 &&
2593 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2594 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2595 )
2596 )
2597 {
2598 /* in case of static WEP, macaddr/bssid is not coming from nl80211
2599 * interface, copy bssid for pairwise key and group macaddr for
2600 * group key initialization*/
2601
2602 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2603
2604 pWextState->roamProfile.negotiatedUCEncryptionType =
2605 pHddStaCtx->conn_info.ucEncryptionType =
2606 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
2607 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
2608 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
2609
2610
2611 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2612 "%s: Negotiated encryption type %d", __func__,
2613 pWextState->roamProfile.negotiatedUCEncryptionType);
2614
2615 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
2616 &pWextState->roamProfile, true);
2617 setKey.keyLength = 0;
2618 setKey.keyDirection = eSIR_TX_RX;
2619
2620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2621 if (pairwise)
2622 {
2623#endif
2624 if (mac_addr)
2625 {
2626 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2627 }
2628 else
2629 {
2630 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
2631 * and peerMacAddress in case of IBSS*/
2632 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
2633 {
2634 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
2635 if (HDD_MAX_NUM_IBSS_STA != staidx)
2636 {
2637 vos_mem_copy(setKey.peerMac,
2638 &pHddStaCtx->conn_info.peerMacAddress[staidx],
2639 WNI_CFG_BSSID_LEN);
2640
2641 }
2642 else
2643 {
2644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
2645 __func__);
2646 return -EOPNOTSUPP;
2647 }
2648 }
2649 else
2650 {
2651 vos_mem_copy(setKey.peerMac,
2652 &pHddStaCtx->conn_info.bssId[0],
2653 WNI_CFG_BSSID_LEN);
2654 }
2655 }
2656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2657 }
2658 else
2659 {
2660 /* set group key*/
2661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2662 "%s- %d: setting Group key",
2663 __func__, __LINE__);
2664 setKey.keyDirection = eSIR_RX_ONLY;
2665 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2666 }
2667#endif
2668 }
2669 else if (
2670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2671 (!pairwise)
2672#else
2673 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2674#endif
2675 )
2676 {
2677 /* set group key*/
2678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2679 "%s- %d: setting Group key",
2680 __func__, __LINE__);
2681 setKey.keyDirection = eSIR_RX_ONLY;
2682 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2683 }
2684 else
2685 {
2686 /* set pairwise key*/
2687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2688 "%s- %d: setting pairwise key",
2689 __func__, __LINE__);
2690 setKey.keyDirection = eSIR_TX_RX;
2691 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2692 }
2693
2694 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2695 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2696 __func__, setKey.peerMac[0], setKey.peerMac[1],
2697 setKey.peerMac[2], setKey.peerMac[3],
2698 setKey.peerMac[4], setKey.peerMac[5],
2699 setKey.keyDirection);
2700
2701 vos_status = wlan_hdd_check_ula_done(pAdapter);
2702
2703 if ( vos_status != VOS_STATUS_SUCCESS )
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
2707 __LINE__, vos_status );
2708
2709 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2710
2711 return -EINVAL;
2712
2713 }
2714
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002715#ifdef WLAN_FEATURE_VOWIFI_11R
2716 /* The supplicant may attempt to set the PTK once pre-authentication is done.
2717 Save the key in the UMAC and include it in the ADD BSS request */
2718 /*TODO 11r - is this used?? */
2719 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
2720 if( halStatus == eHAL_STATUS_SUCCESS )
2721 {
2722 return halStatus;
2723 }
2724#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07002725
2726 /* issue set key request to SME*/
2727 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2728 pAdapter->sessionId, &setKey, &roamId );
2729
2730 if ( 0 != status )
2731 {
2732 hddLog(VOS_TRACE_LEVEL_ERROR,
2733 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
2734 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2735 return -EINVAL;
2736 }
2737
2738
2739 /* in case of IBSS as there was no information available about WEP keys during
2740 * IBSS join, group key intialized with NULL key, so re-initialize group key
2741 * with correct value*/
2742 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
2743 !( ( IW_AUTH_KEY_MGMT_802_1X
2744 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2745 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2746 )
2747 &&
2748 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2749 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2750 )
2751 )
2752 {
2753 setKey.keyDirection = eSIR_RX_ONLY;
2754 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2755
2756 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2757 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2758 __func__, setKey.peerMac[0], setKey.peerMac[1],
2759 setKey.peerMac[2], setKey.peerMac[3],
2760 setKey.peerMac[4], setKey.peerMac[5],
2761 setKey.keyDirection);
2762
2763 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2764 pAdapter->sessionId, &setKey, &roamId );
2765
2766 if ( 0 != status )
2767 {
2768 hddLog(VOS_TRACE_LEVEL_ERROR,
2769 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
2770 __func__, status);
2771 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2772 return -EINVAL;
2773 }
2774 }
2775 }
2776
2777 return 0;
2778}
2779
2780/*
2781 * FUNCTION: wlan_hdd_cfg80211_get_key
2782 * This function is used to get the key information
2783 */
2784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2785static int wlan_hdd_cfg80211_get_key(
2786 struct wiphy *wiphy,
2787 struct net_device *ndev,
2788 u8 key_index, bool pairwise,
2789 const u8 *mac_addr, void *cookie,
2790 void (*callback)(void *cookie, struct key_params*)
2791 )
2792#else
2793static int wlan_hdd_cfg80211_get_key(
2794 struct wiphy *wiphy,
2795 struct net_device *ndev,
2796 u8 key_index, const u8 *mac_addr, void *cookie,
2797 void (*callback)(void *cookie, struct key_params*)
2798 )
2799#endif
2800{
2801 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2802 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2803 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2804 struct key_params params;
2805
2806 ENTER();
2807
2808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2809 __func__,pAdapter->device_mode);
2810
2811 memset(&params, 0, sizeof(params));
2812
2813 if (CSR_MAX_NUM_KEY <= key_index)
2814 {
2815 return -EINVAL;
2816 }
2817
2818 switch(pRoamProfile->EncryptionType.encryptionType[0])
2819 {
2820 case eCSR_ENCRYPT_TYPE_NONE:
2821 params.cipher = IW_AUTH_CIPHER_NONE;
2822 break;
2823
2824 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2825 case eCSR_ENCRYPT_TYPE_WEP40:
2826 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2827 break;
2828
2829 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2830 case eCSR_ENCRYPT_TYPE_WEP104:
2831 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2832 break;
2833
2834 case eCSR_ENCRYPT_TYPE_TKIP:
2835 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2836 break;
2837
2838 case eCSR_ENCRYPT_TYPE_AES:
2839 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2840 break;
2841
2842 default:
2843 params.cipher = IW_AUTH_CIPHER_NONE;
2844 break;
2845 }
2846
2847 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
2848 params.seq_len = 0;
2849 params.seq = NULL;
2850 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
2851 callback(cookie, &params);
2852 return 0;
2853}
2854
2855/*
2856 * FUNCTION: wlan_hdd_cfg80211_del_key
2857 * This function is used to delete the key information
2858 */
2859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2860static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
2861 struct net_device *ndev,
2862 u8 key_index,
2863 bool pairwise,
2864 const u8 *mac_addr
2865 )
2866#else
2867static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
2868 struct net_device *ndev,
2869 u8 key_index,
2870 const u8 *mac_addr
2871 )
2872#endif
2873{
2874 int status = 0;
2875
2876 //This code needs to be revisited. There is sme_removeKey API, we should
2877 //plan to use that. After the change to use correct index in setkey,
2878 //it is observed that this is invalidating peer
2879 //key index whenever re-key is done. This is affecting data link.
2880 //It should be ok to ignore del_key.
2881#if 0
2882 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2883 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2884 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2885 tCsrRoamSetKey setKey;
2886 v_U32_t roamId= 0xFF;
2887
2888 ENTER();
2889
2890 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
2891 __func__,pAdapter->device_mode);
2892
2893 if (CSR_MAX_NUM_KEY <= key_index)
2894 {
2895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2896 key_index);
2897
2898 return -EINVAL;
2899 }
2900
2901 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2902 setKey.keyId = key_index;
2903
2904 if (mac_addr)
2905 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2906 else
2907 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2908
2909 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2910
2911 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2912#ifdef WLAN_FEATURE_P2P
2913 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2914#endif
2915 )
2916 {
2917
2918 hdd_hostapd_state_t *pHostapdState =
2919 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2920 if( pHostapdState->bssState == BSS_START)
2921 {
2922 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2923
2924 if ( status != eHAL_STATUS_SUCCESS )
2925 {
2926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2927 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2928 __LINE__, status );
2929 }
2930 }
2931 }
2932 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2933#ifdef WLAN_FEATURE_P2P
2934 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2935#endif
2936 )
2937 {
2938 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2939
2940 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2941
2942 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2943 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
2944 __func__, setKey.peerMac[0], setKey.peerMac[1],
2945 setKey.peerMac[2], setKey.peerMac[3],
2946 setKey.peerMac[4], setKey.peerMac[5]);
2947 if(pAdapter->sessionCtx.station.conn_info.connState ==
2948 eConnectionState_Associated)
2949 {
2950 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2951 pAdapter->sessionId, &setKey, &roamId );
2952
2953 if ( 0 != status )
2954 {
2955 hddLog(VOS_TRACE_LEVEL_ERROR,
2956 "%s: sme_RoamSetKey failure, returned %d",
2957 __func__, status);
2958 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2959 return -EINVAL;
2960 }
2961 }
2962 }
2963#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002964 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002965 return status;
2966}
2967
2968/*
2969 * FUNCTION: wlan_hdd_cfg80211_set_default_key
2970 * This function is used to set the default tx key index
2971 */
2972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2973static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
2974 struct net_device *ndev,
2975 u8 key_index,
2976 bool unicast, bool multicast)
2977#else
2978static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
2979 struct net_device *ndev,
2980 u8 key_index)
2981#endif
2982{
2983 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2984 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2985 int status = 0;
2986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2987
2988 ENTER();
2989
2990 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
2991 __func__,pAdapter->device_mode, key_index);
2992
2993 if (CSR_MAX_NUM_KEY <= key_index)
2994 {
2995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2996 key_index);
2997
2998 return -EINVAL;
2999 }
3000
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003001 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3002 {
3003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3004 "%s:LOGP in Progress. Ignore!!!", __func__);
3005 return -EAGAIN;
3006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003007
3008 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3009#ifdef WLAN_FEATURE_P2P
3010 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3011#endif
3012 )
3013 {
3014 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3015 (eCSR_ENCRYPT_TYPE_TKIP !=
3016 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3017 (eCSR_ENCRYPT_TYPE_AES !=
3018 pWextState->roamProfile.EncryptionType.encryptionType[0])
3019 )
3020 {
3021 /* if default key index is not same as previous one,
3022 * then update the default key index */
3023
3024 tCsrRoamSetKey setKey;
3025 v_U32_t roamId= 0xFF;
3026 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3027
3028 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3029 __func__, key_index);
3030
3031 Keys->defaultIndex = (u8)key_index;
3032 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3033 setKey.keyId = key_index;
3034 setKey.keyLength = Keys->KeyLength[key_index];
3035
3036 vos_mem_copy(&setKey.Key[0],
3037 &Keys->KeyMaterial[key_index][0],
3038 Keys->KeyLength[key_index]);
3039
3040 setKey.keyDirection = eSIR_TX_ONLY;
3041
3042 vos_mem_copy(setKey.peerMac,
3043 &pHddStaCtx->conn_info.bssId[0],
3044 WNI_CFG_BSSID_LEN);
3045
3046 setKey.encType =
3047 pWextState->roamProfile.EncryptionType.encryptionType[0];
3048
3049 /* issue set key request */
3050 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3051 pAdapter->sessionId, &setKey, &roamId );
3052
3053 if ( 0 != status )
3054 {
3055 hddLog(VOS_TRACE_LEVEL_ERROR,
3056 "%s: sme_RoamSetKey failed, returned %d", __func__,
3057 status);
3058 return -EINVAL;
3059 }
3060 }
3061 }
3062
3063 /* In SoftAp mode setting key direction for default mode */
3064 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3065 {
3066 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3067 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3068 (eCSR_ENCRYPT_TYPE_AES !=
3069 pWextState->roamProfile.EncryptionType.encryptionType[0])
3070 )
3071 {
3072 /* Saving key direction for default key index to TX default */
3073 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3074 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3075 }
3076 }
3077
3078 return status;
3079}
3080
3081/**
3082 * FUNCTION: wlan_hdd_cfg80211_set_channel
3083 * This function is used to set the channel number
3084 */
3085int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
3086 struct ieee80211_channel *chan,
3087 enum nl80211_channel_type channel_type
3088 )
3089{
3090 v_U32_t num_ch = 0;
3091 u32 channel = 0;
3092 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3093 int freq = chan->center_freq; /* freq is in MHZ */
3094
3095 ENTER();
3096
3097 hddLog(VOS_TRACE_LEVEL_INFO,
3098 "%s: device_mode = %d freq = %d \n",__func__,
3099 pAdapter->device_mode, chan->center_freq);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07003100 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3101 {
3102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3103 return -EAGAIN;
3104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003105
3106 /*
3107 * Do freq to chan conversion
3108 * TODO: for 11a
3109 */
3110
3111 channel = ieee80211_frequency_to_channel(freq);
3112
3113 /* Check freq range */
3114 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3115 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
3116 {
3117 hddLog(VOS_TRACE_LEVEL_ERROR,
3118 "%s: Channel [%d] is outside valid range from %d to %d\n",
3119 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3120 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3121 return -EINVAL;
3122 }
3123
3124 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3125
3126 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
3127#ifdef WLAN_FEATURE_P2P
3128 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
3129#endif
3130 )
3131 {
3132 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
3133 {
3134 hddLog(VOS_TRACE_LEVEL_ERROR,
3135 "%s: Invalid Channel [%d] \n", __func__, channel);
3136 return -EINVAL;
3137 }
3138 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3139 "%s: set channel to [%d] for device mode =%d",
3140 __func__, channel,pAdapter->device_mode);
3141 }
3142 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3143#ifdef WLAN_FEATURE_P2P
3144 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3145#endif
3146 )
3147 {
3148 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3149 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
3150 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3151
3152 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
3153 {
3154 /* Link is up then return cant set channel*/
3155 hddLog( VOS_TRACE_LEVEL_ERROR,
3156 "%s: IBSS Associated, can't set the channel\n", __func__);
3157 return -EINVAL;
3158 }
3159
3160 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
3161 pHddStaCtx->conn_info.operationChannel = channel;
3162 pRoamProfile->ChannelInfo.ChannelList =
3163 &pHddStaCtx->conn_info.operationChannel;
3164 }
3165 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3166#ifdef WLAN_FEATURE_P2P
3167 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3168#endif
3169 )
3170 {
3171 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
3172
3173 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3174 {
3175 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3176
3177 /* If auto channel selection is configured as enable/ 1 then ignore
3178 channel set by supplicant
3179 */
3180 if ( cfg_param->apAutoChannelSelection )
3181 {
3182 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
3183
3184 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3185 "%s: set channel to auto channel (0) for device mode =%d",
3186 __func__, pAdapter->device_mode);
3187 }
3188 }
3189 }
3190 else
3191 {
3192 hddLog(VOS_TRACE_LEVEL_FATAL,
3193 "%s: Invalid device mode failed to set valid channel", __func__);
3194 return -EINVAL;
3195 }
3196 EXIT();
3197 return 0;
3198}
3199
3200
3201
3202/*
3203 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3204 * This function is used to inform the BSS details to nl80211 interface.
3205 */
3206static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3207 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3208{
3209 struct net_device *dev = pAdapter->dev;
3210 struct wireless_dev *wdev = dev->ieee80211_ptr;
3211 struct wiphy *wiphy = wdev->wiphy;
3212 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3213 int chan_no;
3214 int ie_length;
3215 const char *ie;
3216 unsigned int freq;
3217 struct ieee80211_channel *chan;
3218 int rssi = 0;
3219 struct cfg80211_bss *bss = NULL;
3220
3221 ENTER();
3222
3223 if( NULL == pBssDesc )
3224 {
3225 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3226 return bss;
3227 }
3228
3229 chan_no = pBssDesc->channelId;
3230 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3231 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3232
3233 if( NULL == ie )
3234 {
3235 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3236 return bss;
3237 }
3238
3239#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3240 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3241 {
3242 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3243 }
3244 else
3245 {
3246 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3247 }
3248#else
3249 freq = ieee80211_channel_to_frequency(chan_no);
3250#endif
3251
3252 chan = __ieee80211_get_channel(wiphy, freq);
3253
3254 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3255 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3256 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3257 if (bss == NULL)
3258 {
3259 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3260
3261 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3262 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3263 pBssDesc->capabilityInfo,
3264 pBssDesc->beaconInterval, ie, ie_length,
3265 rssi, GFP_KERNEL ));
3266}
3267 else
3268 {
3269 return bss;
3270 }
3271}
3272
3273
3274
3275/*
3276 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3277 * This function is used to inform the BSS details to nl80211 interface.
3278 */
3279struct cfg80211_bss*
3280wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3281 tSirBssDescription *bss_desc
3282 )
3283{
3284 /*
3285 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3286 already exists in bss data base of cfg80211 for that particular BSS ID.
3287 Using cfg80211_inform_bss_frame to update the bss entry instead of
3288 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3289 now there is no possibility to get the mgmt(probe response) frame from PE,
3290 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3291 cfg80211_inform_bss_frame.
3292 */
3293 struct net_device *dev = pAdapter->dev;
3294 struct wireless_dev *wdev = dev->ieee80211_ptr;
3295 struct wiphy *wiphy = wdev->wiphy;
3296 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003297#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3298 qcom_ie_age *qie_age = NULL;
3299 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3300#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003303 const char *ie =
3304 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3305 unsigned int freq;
3306 struct ieee80211_channel *chan;
3307 struct ieee80211_mgmt *mgmt =
3308 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3309 struct cfg80211_bss *bss_status = NULL;
3310 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3311 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003312#ifdef WLAN_OPEN_SOURCE
3313 struct timespec ts;
3314#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003315
3316 ENTER();
3317
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003318 if (!mgmt)
3319 return NULL;
3320
Jeff Johnson295189b2012-06-20 16:38:30 -07003321 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003322
3323#ifdef WLAN_OPEN_SOURCE
3324 /* Android does not want the timestamp from the frame.
3325 Instead it wants a monotonic increasing value */
3326 get_monotonic_boottime(&ts);
3327 mgmt->u.probe_resp.timestamp =
3328 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3329#else
3330 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3332 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003333
3334#endif
3335
Jeff Johnson295189b2012-06-20 16:38:30 -07003336 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3337 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003338
3339#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3340 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3341 /* Assuming this is the last IE, copy at the end */
3342 ie_length -=sizeof(qcom_ie_age);
3343 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3344 qie_age->element_id = QCOM_VENDOR_IE_ID;
3345 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3346 qie_age->oui_1 = QCOM_OUI1;
3347 qie_age->oui_2 = QCOM_OUI2;
3348 qie_age->oui_3 = QCOM_OUI3;
3349 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3350 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3351#endif
3352
Jeff Johnson295189b2012-06-20 16:38:30 -07003353 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3354
3355 mgmt->frame_control |=
3356 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3357
3358#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3359 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3360 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3361 {
3362 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3363 }
3364 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3365 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3366
3367 {
3368 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3369 }
3370 else
3371 {
3372 kfree(mgmt);
3373 return NULL;
3374 }
3375#else
3376 freq = ieee80211_channel_to_frequency(chan_no);
3377#endif
3378 chan = __ieee80211_get_channel(wiphy, freq);
3379
3380 /*To keep the rssi icon of the connected AP in the scan window
3381 *and the rssi icon of the wireless networks in sync
3382 * */
3383 if (( eConnectionState_Associated ==
3384 pAdapter->sessionCtx.station.conn_info.connState ) &&
3385 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3386 pAdapter->sessionCtx.station.conn_info.bssId,
3387 WNI_CFG_BSSID_LEN)))
3388 {
3389 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3390 rssi = (pAdapter->rssi * 100);
3391 }
3392 else
3393 {
3394 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3395 }
3396
3397 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3398 frame_len, rssi, GFP_KERNEL);
3399 kfree(mgmt);
3400 return bss_status;
3401}
3402
3403/*
3404 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3405 * This function is used to update the BSS data base of CFG8011
3406 */
3407struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3408 tCsrRoamInfo *pRoamInfo
3409 )
3410{
3411 tCsrRoamConnectedProfile roamProfile;
3412 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3413 struct cfg80211_bss *bss = NULL;
3414
3415 ENTER();
3416
3417 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3418 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3419
3420 if (NULL != roamProfile.pBssDesc)
3421 {
3422 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3423 &roamProfile);
3424
3425 if (NULL == bss)
3426 {
3427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3428 __func__);
3429 }
3430
3431 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3432 }
3433 else
3434 {
3435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3436 __func__);
3437 }
3438 return bss;
3439}
3440
3441/*
3442 * FUNCTION: wlan_hdd_cfg80211_update_bss
3443 */
3444static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3445 hdd_adapter_t *pAdapter
3446 )
3447{
3448 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3449 tCsrScanResultInfo *pScanResult;
3450 eHalStatus status = 0;
3451 tScanResultHandle pResult;
3452 struct cfg80211_bss *bss_status = NULL;
3453
3454 ENTER();
3455
3456 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3457 {
3458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3459 return -EAGAIN;
3460 }
3461
3462 /*
3463 * start getting scan results and populate cgf80211 BSS database
3464 */
3465 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3466
3467 /* no scan results */
3468 if (NULL == pResult)
3469 {
3470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3471 return status;
3472 }
3473
3474 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3475
3476 while (pScanResult)
3477 {
3478 /*
3479 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3480 * entry already exists in bss data base of cfg80211 for that
3481 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3482 * bss entry instead of cfg80211_inform_bss, But this call expects
3483 * mgmt packet as input. As of now there is no possibility to get
3484 * the mgmt(probe response) frame from PE, converting bss_desc to
3485 * ieee80211_mgmt(probe response) and passing to c
3486 * fg80211_inform_bss_frame.
3487 * */
3488
3489 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3490 &pScanResult->BssDescriptor);
3491
3492
3493 if (NULL == bss_status)
3494 {
3495 hddLog(VOS_TRACE_LEVEL_INFO,
3496 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3497 }
3498 else
3499 {
3500 cfg80211_put_bss(bss_status);
3501 }
3502
3503 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3504 }
3505
3506 sme_ScanResultPurge(hHal, pResult);
3507
3508 return 0;
3509}
3510
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003511void
3512hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3513{
3514 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003515 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3516 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3517 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003518} /****** end hddPrintMacAddr() ******/
3519
3520void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003521hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003522{
3523 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003524 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3525 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3526 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3527 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003528} /****** end hddPrintPmkId() ******/
3529
3530//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3531//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3532
3533//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3534//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3535
3536#define dump_bssid(bssid) \
3537 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003538 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3539 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3540 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003541 }
3542
3543#define dump_pmkid(pMac, pmkid) \
3544 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003545 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3546 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3547 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003548 }
3549
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003550#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003551/*
3552 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3553 * This function is used to notify the supplicant of a new PMKSA candidate.
3554 */
3555int wlan_hdd_cfg80211_pmksa_candidate_notify(
3556 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3557 int index, bool preauth )
3558{
Jeff Johnsone7245742012-09-05 17:12:55 -07003559#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003560 struct net_device *dev = pAdapter->dev;
3561
3562 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003563 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003564
3565 if( NULL == pRoamInfo )
3566 {
3567 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3568 return -EINVAL;
3569 }
3570
3571 dump_bssid(pRoamInfo->bssid);
3572 cfg80211_pmksa_candidate_notify(dev, index,
3573 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003574#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003575 return 0;
3576}
3577#endif //FEATURE_WLAN_LFR
3578
Jeff Johnson295189b2012-06-20 16:38:30 -07003579/*
3580 * FUNCTION: hdd_cfg80211_scan_done_callback
3581 * scanning callback function, called after finishing scan
3582 *
3583 */
3584static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3585 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3586{
3587 struct net_device *dev = (struct net_device *) pContext;
3588 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003590 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3591 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 struct cfg80211_scan_request *req = NULL;
3593 int ret = 0;
3594
3595 ENTER();
3596
3597 hddLog(VOS_TRACE_LEVEL_INFO,
3598 "%s called with halHandle = %p, pContext = %p,"
3599 "scanID = %d, returned status = %d\n",
3600 __func__, halHandle, pContext, (int) scanId, (int) status);
3601
3602 //Block on scan req completion variable. Can't wait forever though.
3603 ret = wait_for_completion_interruptible_timeout(
3604 &pScanInfo->scan_req_completion_event,
3605 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3606 if (!ret)
3607 {
3608 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003609 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 }
3611
3612 if(pScanInfo->mScanPending != VOS_TRUE)
3613 {
3614 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003615 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003616 }
3617
3618 /* Check the scanId */
3619 if (pScanInfo->scanId != scanId)
3620 {
3621 hddLog(VOS_TRACE_LEVEL_INFO,
3622 "%s called with mismatched scanId pScanInfo->scanId = %d "
3623 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3624 (int) scanId);
3625 }
3626
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3628 pAdapter);
3629
3630 if (0 > ret)
3631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3632
3633
3634 /* If any client wait scan result through WEXT
3635 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003636 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 {
3638 /* The other scan request waiting for current scan finish
3639 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003640 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003642 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003643 }
3644 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003645 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 {
3647 struct net_device *dev = pAdapter->dev;
3648 union iwreq_data wrqu;
3649 int we_event;
3650 char *msg;
3651
3652 memset(&wrqu, '\0', sizeof(wrqu));
3653 we_event = SIOCGIWSCAN;
3654 msg = NULL;
3655 wireless_send_event(dev, we_event, &wrqu, msg);
3656 }
3657 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003658 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003659
3660 /* Get the Scan Req */
3661 req = pAdapter->request;
3662
3663 if (!req)
3664 {
3665 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003666 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003667 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003668 }
3669
3670 /*
3671 * setting up 0, just in case.
3672 */
3673 req->n_ssids = 0;
3674 req->n_channels = 0;
3675 req->ie = 0;
3676
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07003678 /* Scan is no longer pending */
3679 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003680
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07003681 /*
3682 * cfg80211_scan_done informing NL80211 about completion
3683 * of scanning
3684 */
3685 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08003686 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07003687#ifdef WLAN_FEATURE_P2P
3688 /* Flush out scan result after p2p_serach is done */
Jeff Johnsone7245742012-09-05 17:12:55 -07003689 if(pScanInfo->flushP2pScanResults)
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 {
3691 tANI_U8 sessionId = pAdapter->sessionId;
Madan Mohan Koyyalamudiab41d0f2012-10-31 17:17:10 -07003692 sme_ScanFlushP2PResult(WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId);
Jeff Johnsone7245742012-09-05 17:12:55 -07003693 pScanInfo->flushP2pScanResults = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003694 }
3695#endif
3696
Jeff Johnsone7245742012-09-05 17:12:55 -07003697allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003698 /* release the wake lock at the end of the scan*/
3699 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003700
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07003701 /* Acquire wakelock to handle the case where APP's tries to suspend
3702 * immediatly after the driver gets connect request(i.e after scan)
3703 * from supplicant, this result in app's is suspending and not able
3704 * to process the connect request to AP */
3705 hdd_allow_suspend_timeout(100);
3706
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 EXIT();
3708 return 0;
3709}
3710
3711/*
3712 * FUNCTION: wlan_hdd_cfg80211_scan
3713 * this scan respond to scan trigger and update cfg80211 scan database
3714 * later, scan dump command can be used to recieve scan results
3715 */
3716int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, struct net_device *dev,
3717 struct cfg80211_scan_request *request)
3718{
3719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3720 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3721 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3722 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3723 tCsrScanRequest scanRequest;
3724 tANI_U8 *channelList = NULL, i;
3725 v_U32_t scanId = 0;
3726 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003727 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003728#ifdef WLAN_FEATURE_P2P
3729 v_U8_t* pP2pIe = NULL;
3730#endif
3731
3732 ENTER();
3733
3734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3735 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003736
3737 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
3738 (eConnectionState_Connecting ==
3739 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
3740 {
3741 hddLog(VOS_TRACE_LEVEL_ERROR,
3742 "%s: Connection in progress: Scan request denied (EBUSY)", __func__);
3743 return -EBUSY;
3744 }
3745
Jeff Johnson295189b2012-06-20 16:38:30 -07003746#ifdef WLAN_BTAMP_FEATURE
3747 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003748 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07003749 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003750 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003751 "%s: No scanning when AMP is on", __func__);
3752 return -EOPNOTSUPP;
3753 }
3754#endif
3755 //Scan on any other interface is not supported.
3756 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
3757 {
3758 hddLog(VOS_TRACE_LEVEL_ERROR,
3759 "%s: Not scanning on device_mode = %d",
3760 __func__, pAdapter->device_mode);
3761 return -EOPNOTSUPP;
3762 }
3763
3764 if (TRUE == pScanInfo->mScanPending)
3765 {
3766 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
3767 return -EBUSY;
3768 }
3769
3770 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3771 {
3772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3773 "%s:LOGP in Progress. Ignore!!!", __func__);
3774 return -EAGAIN;
3775 }
3776
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07003777 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
3778 {
3779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3780 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
3781 return -EAGAIN;
3782 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07003783 //Don't Allow Scan and return busy if Remain On
3784 //Channel and action frame is pending
3785 //Otherwise Cancel Remain On Channel and allow Scan
3786 //If no action frame pending
3787 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
3788 {
3789 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
3790 return -EBUSY;
3791 }
3792
Jeff Johnson295189b2012-06-20 16:38:30 -07003793 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
3794 {
3795 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
3796 "%s: Aquire lock fail", __func__);
3797 return -EAGAIN;
3798 }
3799 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
3800 {
3801 hddLog(VOS_TRACE_LEVEL_WARN,
3802 "%s: MAX TM Level Scan not allowed", __func__);
3803 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3804 return -EBUSY;
3805 }
3806 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3807
3808 vos_mem_zero( &scanRequest, sizeof(scanRequest));
3809
3810 if (NULL != request)
3811 {
3812 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
3813 (int)request->n_ssids);
3814
3815 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
3816 * Becasue of this, driver is assuming that this is not wildcard scan and so
3817 * is not aging out the scan results.
3818 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07003819 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07003820 {
3821 request->n_ssids = 0;
3822 }
3823
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003824 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07003825 {
3826 tCsrSSIDInfo *SsidInfo;
3827 int j;
3828 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
3829 /* Allocate num_ssid tCsrSSIDInfo structure */
3830 SsidInfo = scanRequest.SSIDs.SSIDList =
3831 ( tCsrSSIDInfo *)vos_mem_malloc(
3832 request->n_ssids*sizeof(tCsrSSIDInfo));
3833
3834 if(NULL == scanRequest.SSIDs.SSIDList)
3835 {
3836 hddLog(VOS_TRACE_LEVEL_ERROR,
3837 "memory alloc failed SSIDInfo buffer");
3838 return -ENOMEM;
3839 }
3840
3841 /* copy all the ssid's and their length */
3842 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
3843 {
3844 /* get the ssid length */
3845 SsidInfo->SSID.length = request->ssids[j].ssid_len;
3846 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
3847 SsidInfo->SSID.length);
3848 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
3849 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
3850 j, SsidInfo->SSID.ssId);
3851 }
3852 /* set the scan type to active */
3853 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3854 }
3855 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
3856 {
3857 /* set the scan type to active */
3858 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3859 }
3860 else
3861 {
3862 /*Set the scan type to default type, in this case it is ACTIVE*/
3863 scanRequest.scanType = pScanInfo->scan_mode;
3864 }
3865 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
3866 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
3867 }
3868 else
3869 {
3870 /* set the scan type to active */
3871 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3872 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
3873
3874 /* set min and max channel time to zero */
3875 scanRequest.minChnTime = 0;
3876 scanRequest.maxChnTime = 0;
3877 }
3878
3879 /* set BSSType to default type */
3880 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
3881
3882 /*TODO: scan the requested channels only*/
3883
3884 /*Right now scanning all the channels */
3885 if( request )
3886 {
3887 if( request->n_channels )
3888 {
3889 channelList = vos_mem_malloc( request->n_channels );
3890 if( NULL == channelList )
3891 {
3892 status = -ENOMEM;
3893 goto free_mem;
3894 }
3895
3896 for( i = 0 ; i < request->n_channels ; i++ )
3897 channelList[i] = request->channels[i]->hw_value;
3898 }
3899
3900 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
3901 scanRequest.ChannelInfo.ChannelList = channelList;
3902
3903 /* set requestType to full scan */
3904 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
3905
3906 if( request->ie_len )
3907 {
3908 /* save this for future association (join requires this) */
3909 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
3910 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
3911 pScanInfo->scanAddIE.length = request->ie_len;
3912
3913 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07003914 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
3915 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 )
3917 {
3918 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
3919 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
3920 }
3921
3922 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
3923 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
3924
3925#ifdef WLAN_FEATURE_P2P
3926 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
3927 request->ie_len);
3928 if (pP2pIe != NULL)
3929 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07003930#ifdef WLAN_FEATURE_P2P_DEBUG
3931 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
3932 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
3933 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
3934 {
3935 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
3936 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
3937 "Go nego completed to Connection is started");
3938 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
3939 "for 8way Handshake");
3940 }
3941 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
3942 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
3943 {
3944 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
3945 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
3946 "Disconnected state to Connection is started");
3947 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
3948 "for 4way Handshake");
3949 }
3950#endif
3951
Jeff Johnsone7245742012-09-05 17:12:55 -07003952 /* no_cck will be set during p2p find to disable 11b rates */
3953 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07003954 {
3955 tANI_U8 sessionId = pAdapter->sessionId;
3956 hddLog(VOS_TRACE_LEVEL_INFO,
3957 "%s: This is a P2P Search", __func__);
3958 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07003959
3960 /* Flush the scan results only for P2P search.
3961 P2P search happens on 3 social channels (1, 6, 11) */
3962 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
3963 {
3964 pScanInfo->flushP2pScanResults = 1;
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07003965 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnsone7245742012-09-05 17:12:55 -07003966 sessionId );
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07003967 /* set requestType to P2P Discovery */
3968 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07003969 }
3970
3971 /*
3972 Skip Dfs Channel in case of P2P Search
3973 if it is set in ini file
3974 */
3975 if(cfg_param->skipDfsChnlInP2pSearch)
3976 {
3977 scanRequest.skipDfsChnlInP2pSearch = 1;
3978 }
3979 else
3980 {
3981 scanRequest.skipDfsChnlInP2pSearch = 0;
3982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003983
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 }
3985 }
3986#endif
3987 }
3988 }
3989
3990 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
3991
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003992 /* acquire the wakelock to avoid the apps suspend during the scan. To
3993 * address the following issues.
3994 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
3995 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
3996 * for long time, this result in apps running at full power for long time.
3997 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
3998 * be stuck in full power because of resume BMPS
3999 */
4000 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004001
4002 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004003 pAdapter->sessionId, &scanRequest, &scanId,
4004 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004005
Jeff Johnson295189b2012-06-20 16:38:30 -07004006 if (eHAL_STATUS_SUCCESS != status)
4007 {
4008 hddLog(VOS_TRACE_LEVEL_ERROR,
4009 "%s: sme_ScanRequest returned error %d", __func__, status);
4010 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004011 if(eHAL_STATUS_RESOURCES == status)
4012 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004013 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 -07004014 status = -EBUSY;
4015 } else {
4016 status = -EIO;
4017 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004018 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004019 goto free_mem;
4020 }
4021
4022 pScanInfo->mScanPending = TRUE;
4023 pAdapter->request = request;
4024 pScanInfo->scanId = scanId;
4025
4026 complete(&pScanInfo->scan_req_completion_event);
4027
4028free_mem:
4029 if( scanRequest.SSIDs.SSIDList )
4030 {
4031 vos_mem_free(scanRequest.SSIDs.SSIDList);
4032 }
4033
4034 if( channelList )
4035 vos_mem_free( channelList );
4036
4037 EXIT();
4038
4039 return status;
4040}
4041
4042/*
4043 * FUNCTION: wlan_hdd_cfg80211_connect_start
4044 * This function is used to start the association process
4045 */
4046int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004047 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004048{
4049 int status = 0;
4050 hdd_wext_state_t *pWextState;
4051 v_U32_t roamId;
4052 tCsrRoamProfile *pRoamProfile;
4053 eMib_dot11DesiredBssType connectedBssType;
4054 eCsrAuthType RSNAuthType;
4055
4056 ENTER();
4057
4058 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4059
4060 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4061 {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4063 return -EINVAL;
4064 }
4065
4066 pRoamProfile = &pWextState->roamProfile;
4067
4068 if (pRoamProfile)
4069 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004070 int ret = 0;
4071 hdd_station_ctx_t *pHddStaCtx;
4072 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4073 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4074
4075 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4076 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4077 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004078 {
4079 /* Issue disconnect to CSR */
4080 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4081 if( eHAL_STATUS_SUCCESS ==
4082 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4083 pAdapter->sessionId,
4084 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4085 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004086 ret = wait_for_completion_interruptible_timeout(
4087 &pAdapter->disconnect_comp_var,
4088 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4089 if (0 == ret)
4090 {
4091 VOS_ASSERT(0);
4092 }
4093 }
4094 }
4095 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4096 {
4097 ret = wait_for_completion_interruptible_timeout(
4098 &pAdapter->disconnect_comp_var,
4099 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4100 if (0 == ret)
4101 {
4102 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004103 }
4104 }
4105
4106 if (HDD_WMM_USER_MODE_NO_QOS ==
4107 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4108 {
4109 /*QoS not enabled in cfg file*/
4110 pRoamProfile->uapsd_mask = 0;
4111 }
4112 else
4113 {
4114 /*QoS enabled, update uapsd mask from cfg file*/
4115 pRoamProfile->uapsd_mask =
4116 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4117 }
4118
4119 pRoamProfile->SSIDs.numOfSSIDs = 1;
4120 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4121 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4122 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4123 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4124 ssid, ssid_len);
4125
4126 if (bssid)
4127 {
4128 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4129 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4130 WNI_CFG_BSSID_LEN);
4131 /* Save BSSID in seperate variable as well, as RoamProfile
4132 BSSID is getting zeroed out in the association process. And in
4133 case of join failure we should send valid BSSID to supplicant
4134 */
4135 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4136 WNI_CFG_BSSID_LEN);
4137 }
4138
4139 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4140 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4141 {
4142 /*set gen ie*/
4143 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4144 /*set auth*/
4145 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4146 }
4147 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4148 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4149 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4150 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4151 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4152 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4153 )
4154 {
4155 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4156 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4157 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4158 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4159 eCSR_AUTH_TYPE_AUTOSWITCH;
4160 pWextState->roamProfile.AuthType.authType[0] =
4161 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4162 }
4163#ifdef FEATURE_WLAN_WAPI
4164 if (pAdapter->wapi_info.nWapiMode)
4165 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004166 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 switch (pAdapter->wapi_info.wapiAuthMode)
4168 {
4169 case WAPI_AUTH_MODE_PSK:
4170 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004171 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 pAdapter->wapi_info.wapiAuthMode);
4173 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4174 break;
4175 }
4176 case WAPI_AUTH_MODE_CERT:
4177 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004178 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 pAdapter->wapi_info.wapiAuthMode);
4180 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4181 break;
4182 }
4183 } // End of switch
4184 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4185 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4186 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004187 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 pRoamProfile->AuthType.numEntries = 1;
4189 pRoamProfile->EncryptionType.numEntries = 1;
4190 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4191 pRoamProfile->mcEncryptionType.numEntries = 1;
4192 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4193 }
4194 }
4195#endif /* FEATURE_WLAN_WAPI */
4196 pRoamProfile->csrPersona = pAdapter->device_mode;
4197
Jeff Johnson32d95a32012-09-10 13:15:23 -07004198 if( operatingChannel )
4199 {
4200 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4201 pRoamProfile->ChannelInfo.numOfChannels = 1;
4202 }
4203
Jeff Johnson295189b2012-06-20 16:38:30 -07004204 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4205 pAdapter->sessionId, pRoamProfile, &roamId);
4206
Jeff Johnson32d95a32012-09-10 13:15:23 -07004207 pRoamProfile->ChannelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004208 pRoamProfile->ChannelInfo.numOfChannels = 0;
4209 }
4210 else
4211 {
4212 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4213 return -EINVAL;
4214 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004215
4216 if( WLAN_HDD_INFRA_STATION == pAdapter->device_mode )
4217 {
4218 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState =
4219 eConnectionState_Connecting;
4220 }
4221
4222 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 return status;
4224}
4225
4226/*
4227 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4228 * This function is used to set the authentication type (OPEN/SHARED).
4229 *
4230 */
4231static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4232 enum nl80211_auth_type auth_type)
4233{
4234 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4235 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4236
4237 ENTER();
4238
4239 /*set authentication type*/
4240 switch (auth_type)
4241 {
4242 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4243 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004244#ifdef WLAN_FEATURE_VOWIFI_11R
4245 case NL80211_AUTHTYPE_FT:
4246#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004247 hddLog(VOS_TRACE_LEVEL_INFO,
4248 "%s: set authentication type to OPEN", __func__);
4249 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4250 break;
4251
4252 case NL80211_AUTHTYPE_SHARED_KEY:
4253 hddLog(VOS_TRACE_LEVEL_INFO,
4254 "%s: set authentication type to SHARED", __func__);
4255 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4256 break;
4257#ifdef FEATURE_WLAN_CCX
4258 case NL80211_AUTHTYPE_NETWORK_EAP:
4259 hddLog(VOS_TRACE_LEVEL_INFO,
4260 "%s: set authentication type to CCKM WPA", __func__);
4261 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4262 break;
4263#endif
4264
4265
4266 default:
4267 hddLog(VOS_TRACE_LEVEL_ERROR,
4268 "%s: Unsupported authentication type %d", __func__,
4269 auth_type);
4270 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4271 return -EINVAL;
4272 }
4273
4274 pWextState->roamProfile.AuthType.authType[0] =
4275 pHddStaCtx->conn_info.authType;
4276 return 0;
4277}
4278
4279/*
4280 * FUNCTION: wlan_hdd_set_akm_suite
4281 * This function is used to set the key mgmt type(PSK/8021x).
4282 *
4283 */
4284static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4285 u32 key_mgmt
4286 )
4287{
4288 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4289 ENTER();
4290
4291 /*set key mgmt type*/
4292 switch(key_mgmt)
4293 {
4294 case WLAN_AKM_SUITE_PSK:
4295 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4296 __func__);
4297 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4298 break;
4299
4300 case WLAN_AKM_SUITE_8021X:
4301 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4302 __func__);
4303 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4304 break;
4305#ifdef FEATURE_WLAN_CCX
4306#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4307#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4308 case WLAN_AKM_SUITE_CCKM:
4309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4310 __func__);
4311 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4312 break;
4313#endif
4314
4315 default:
4316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4317 __func__, key_mgmt);
4318 return -EINVAL;
4319
4320 }
4321 return 0;
4322}
4323
4324/*
4325 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4326 * This function is used to set the encryption type
4327 * (NONE/WEP40/WEP104/TKIP/CCMP).
4328 */
4329static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4330 u32 cipher,
4331 bool ucast
4332 )
4333{
4334 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4335 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4336 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4337
4338 ENTER();
4339
4340 if (!cipher)
4341 {
4342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4343 __func__, cipher);
4344 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4345 }
4346 else
4347 {
4348
4349 /*set encryption method*/
4350 switch (cipher)
4351 {
4352 case IW_AUTH_CIPHER_NONE:
4353 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4354 break;
4355
4356 case WLAN_CIPHER_SUITE_WEP40:
4357 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4358 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4359 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4360 else
4361 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4362 break;
4363
4364 case WLAN_CIPHER_SUITE_WEP104:
4365 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4366 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4367 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4368 else
4369 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4370 break;
4371
4372 case WLAN_CIPHER_SUITE_TKIP:
4373 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4374 break;
4375
4376 case WLAN_CIPHER_SUITE_CCMP:
4377 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4378 break;
4379#ifdef FEATURE_WLAN_WAPI
4380 case WLAN_CIPHER_SUITE_SMS4:
4381 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4382 break;
4383#endif
4384
4385#ifdef FEATURE_WLAN_CCX
4386 case WLAN_CIPHER_SUITE_KRK:
4387 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4388 break;
4389#endif
4390 default:
4391 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4392 __func__, cipher);
4393 return -EOPNOTSUPP;
4394 }
4395 }
4396
4397 if (ucast)
4398 {
4399 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4400 __func__, encryptionType);
4401 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4402 pWextState->roamProfile.EncryptionType.numEntries = 1;
4403 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4404 encryptionType;
4405 }
4406 else
4407 {
4408 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4409 __func__, encryptionType);
4410 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4411 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4412 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4413 }
4414
4415 return 0;
4416}
4417
4418
4419/*
4420 * FUNCTION: wlan_hdd_cfg80211_set_ie
4421 * This function is used to parse WPA/RSN IE's.
4422 */
4423int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4424 u8 *ie,
4425 size_t ie_len
4426 )
4427{
4428 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4429 u8 *genie = ie;
4430 v_U16_t remLen = ie_len;
4431#ifdef FEATURE_WLAN_WAPI
4432 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4433 u16 *tmp;
4434 v_U16_t akmsuiteCount;
4435 int *akmlist;
4436#endif
4437 ENTER();
4438
4439 /* clear previous assocAddIE */
4440 pWextState->assocAddIE.length = 0;
4441 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4442
4443 while (remLen >= 2)
4444 {
4445 v_U16_t eLen = 0;
4446 v_U8_t elementId;
4447 elementId = *genie++;
4448 eLen = *genie++;
4449 remLen -= 2;
4450
4451 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4452 __func__, elementId, eLen);
4453
4454 switch ( elementId )
4455 {
4456 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004457 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 -07004458 {
4459 hddLog(VOS_TRACE_LEVEL_ERROR,
4460 "%s: Invalid WPA IE", __func__);
4461 return -EINVAL;
4462 }
4463 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4464 {
4465 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4466 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4467 __func__, eLen + 2);
4468
4469 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4470 {
4471 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE. "
4472 "Need bigger buffer space\n");
4473 VOS_ASSERT(0);
4474 return -ENOMEM;
4475 }
4476 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4477 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4478 pWextState->assocAddIE.length += eLen + 2;
4479
4480 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4481 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4482 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4483 }
4484 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4485 {
4486 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4487 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4488 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4489 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4490 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4491 }
4492#ifdef WLAN_FEATURE_P2P
4493 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4494 P2P_OUI_TYPE_SIZE))
4495 /*Consider P2P IE, only for P2P Client */
4496 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4497 {
4498 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4499 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4500 __func__, eLen + 2);
4501
4502 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4503 {
4504 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4505 "Need bigger buffer space\n");
4506 VOS_ASSERT(0);
4507 return -ENOMEM;
4508 }
4509 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4510 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4511 pWextState->assocAddIE.length += eLen + 2;
4512
4513 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4514 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4515 }
4516#endif
4517#ifdef WLAN_FEATURE_WFD
4518 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4519 WFD_OUI_TYPE_SIZE))
4520 /*Consider WFD IE, only for P2P Client */
4521 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4522 {
4523 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4524 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4525 __func__, eLen + 2);
4526
4527 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4528 {
4529 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4530 "Need bigger buffer space\n");
4531 VOS_ASSERT(0);
4532 return -ENOMEM;
4533 }
4534 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4535 // WPS IE + P2P IE + WFD IE
4536 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4537 pWextState->assocAddIE.length += eLen + 2;
4538
4539 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4540 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4541 }
4542#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004543 /* Appending HS 2.0 Indication Element in Assiciation Request */
4544 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004545 HS20_OUI_TYPE_SIZE)) )
4546 {
4547 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4548 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4549 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004550
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004551 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4552 {
4553 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4554 "Need bigger buffer space\n");
4555 VOS_ASSERT(0);
4556 return -ENOMEM;
4557 }
4558 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4559 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004560
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004561 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4562 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4563 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004564
Jeff Johnson295189b2012-06-20 16:38:30 -07004565 break;
4566 case DOT11F_EID_RSN:
4567 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4568 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4569 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4570 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4571 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4572 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004573 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4574 case DOT11F_EID_EXTCAP:
4575 {
4576 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4577 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
4578 __func__, eLen + 2);
4579
4580 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4581 {
4582 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4583 "Need bigger buffer space\n");
4584 VOS_ASSERT(0);
4585 return -ENOMEM;
4586 }
4587 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4588 pWextState->assocAddIE.length += eLen + 2;
4589
4590 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4591 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4592 break;
4593 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004594#ifdef FEATURE_WLAN_WAPI
4595 case WLAN_EID_WAPI:
4596 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
4597 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
4598 pAdapter->wapi_info.nWapiMode);
4599 tmp = (u16 *)ie;
4600 tmp = tmp + 2; // Skip element Id and Len, Version
4601 akmsuiteCount = WPA_GET_LE16(tmp);
4602 tmp = tmp + 1;
4603 akmlist = (int *)(tmp);
4604 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
4605 {
4606 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
4607 }
4608 else
4609 {
4610 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
4611 VOS_ASSERT(0);
4612 return -EINVAL;
4613 }
4614
4615 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
4616 {
4617 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004618 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004619 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
4620 }
4621 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
4622 {
4623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004624 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004625 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
4626 }
4627 break;
4628#endif
4629 default:
4630 hddLog (VOS_TRACE_LEVEL_ERROR,
4631 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004632 /* when Unknown IE is received we should break and continue
4633 * to the next IE in the buffer instead we were returning
4634 * so changing this to break */
4635 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07004636 }
4637 genie += eLen;
4638 remLen -= eLen;
4639 }
4640 EXIT();
4641 return 0;
4642}
4643
4644/*
4645 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4646 * This function is used to initialize the security
4647 * parameters during connect operation.
4648 */
4649int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
4650 struct cfg80211_connect_params *req
4651 )
4652{
4653 int status = 0;
4654 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4655 ENTER();
4656
4657 /*set wpa version*/
4658 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4659
4660 if (req->crypto.wpa_versions)
4661 {
4662 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
4663 && ( (req->ie_len)
4664 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
4665 // Make sure that it is including a WPA IE.
4666 /* Currently NL is putting WPA version 1 even for open,
4667 * since p2p ie is also put in same buffer.
4668 * */
4669 {
4670 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
4671 }
4672 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
4673 {
4674 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
4675 }
4676 }
4677
4678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
4679 pWextState->wpaVersion);
4680
4681 /*set authentication type*/
4682 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
4683
4684 if (0 > status)
4685 {
4686 hddLog(VOS_TRACE_LEVEL_ERROR,
4687 "%s: failed to set authentication type ", __func__);
4688 return status;
4689 }
4690
4691 /*set key mgmt type*/
4692 if (req->crypto.n_akm_suites)
4693 {
4694 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
4695 if (0 > status)
4696 {
4697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
4698 __func__);
4699 return status;
4700 }
4701 }
4702
4703 /*set pairwise cipher type*/
4704 if (req->crypto.n_ciphers_pairwise)
4705 {
4706 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
4707 req->crypto.ciphers_pairwise[0], true);
4708 if (0 > status)
4709 {
4710 hddLog(VOS_TRACE_LEVEL_ERROR,
4711 "%s: failed to set unicast cipher type", __func__);
4712 return status;
4713 }
4714 }
4715 else
4716 {
4717 /*Reset previous cipher suite to none*/
4718 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
4719 if (0 > status)
4720 {
4721 hddLog(VOS_TRACE_LEVEL_ERROR,
4722 "%s: failed to set unicast cipher type", __func__);
4723 return status;
4724 }
4725 }
4726
4727 /*set group cipher type*/
4728 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
4729 false);
4730
4731 if (0 > status)
4732 {
4733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
4734 __func__);
4735 return status;
4736 }
4737
4738 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
4739 if (req->ie_len)
4740 {
4741 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
4742 if ( 0 > status)
4743 {
4744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
4745 __func__);
4746 return status;
4747 }
4748 }
4749
4750 /*incase of WEP set default key information*/
4751 if (req->key && req->key_len)
4752 {
4753 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
4754 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
4755 )
4756 {
4757 if ( IW_AUTH_KEY_MGMT_802_1X
4758 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
4759 {
4760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
4761 __func__);
4762 return -EOPNOTSUPP;
4763 }
4764 else
4765 {
4766 u8 key_len = req->key_len;
4767 u8 key_idx = req->key_idx;
4768
4769 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
4770 && (CSR_MAX_NUM_KEY > key_idx)
4771 )
4772 {
4773 hddLog(VOS_TRACE_LEVEL_INFO,
4774 "%s: setting default wep key, key_idx = %hu key_len %hu",
4775 __func__, key_idx, key_len);
4776 vos_mem_copy(
4777 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
4778 req->key, key_len);
4779 pWextState->roamProfile.Keys.KeyLength[key_idx] =
4780 (u8)key_len;
4781 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
4782 }
4783 }
4784 }
4785 }
4786
4787 return status;
4788}
4789
4790/*
4791 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4792 * This function is used to initialize the security
4793 * parameters during connect operation.
4794 */
4795static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
4796 struct net_device *ndev,
4797 struct cfg80211_connect_params *req
4798 )
4799{
4800 int status = 0;
4801 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4802 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
4803 hdd_context_t *pHddCtx = NULL;
4804
4805 ENTER();
4806
4807 hddLog(VOS_TRACE_LEVEL_INFO,
4808 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
4809
4810 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
4811 {
4812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4813 "%s:LOGP in Progress. Ignore!!!", __func__);
4814 return -EAGAIN;
4815 }
4816
4817#ifdef WLAN_BTAMP_FEATURE
4818 //Infra connect not supported when AMP traffic is on.
4819 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
4820 {
4821 hddLog(VOS_TRACE_LEVEL_ERROR,
4822 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004823 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 }
4825#endif
4826 /*initialise security parameters*/
4827 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
4828
4829 if ( 0 > status)
4830 {
4831 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
4832 __func__);
4833 return status;
4834 }
4835
4836 //If Device Mode is Station Concurrent Sessions Exit BMps
4837 //P2P Mode will be taken care in Open/close adaptor
4838 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4839 (vos_concurrent_sessions_running()))
4840 {
4841 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
4842
4843 if (NULL != pVosContext)
4844 {
4845 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
4846 if(NULL != pHddCtx)
4847 {
4848 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
4849 }
4850 }
4851 }
4852
Mohit Khanna765234a2012-09-11 15:08:35 -07004853 if ( req->channel )
4854 {
4855 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
4856 req->ssid_len, req->bssid,
4857 req->channel->hw_value);
4858 }
4859 else
4860 {
4861 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
4862 req->ssid_len, req->bssid,
4863 0);
4864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004865
4866 if (0 > status)
4867 {
4868 //ReEnable BMPS if disabled
4869 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
4870 (NULL != pHddCtx))
4871 {
4872 //ReEnable Bmps and Imps back
4873 hdd_enable_bmps_imps(pHddCtx);
4874 }
4875
4876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
4877 return status;
4878 }
4879 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
4880 EXIT();
4881 return status;
4882}
4883
4884
4885/*
4886 * FUNCTION: wlan_hdd_cfg80211_disconnect
4887 * This function is used to issue a disconnect request to SME
4888 */
4889static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
4890 struct net_device *dev,
4891 u16 reason
4892 )
4893{
4894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4895 tCsrRoamProfile *pRoamProfile =
4896 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
4897 int status = 0;
4898 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4899
4900 ENTER();
4901
4902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4903 __func__,pAdapter->device_mode);
4904
4905 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
4906 __func__, reason);
4907
4908 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4909 {
4910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4911 "%s:LOGP in Progress. Ignore!!!",__func__);
4912 return -EAGAIN;
4913 }
4914 if (NULL != pRoamProfile)
4915 {
4916 /*issue disconnect request to SME, if station is in connected state*/
4917 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
4918 {
4919 eCsrRoamDisconnectReason reasonCode =
4920 eCSR_DISCONNECT_REASON_UNSPECIFIED;
4921 switch(reason)
4922 {
4923 case WLAN_REASON_MIC_FAILURE:
4924 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
4925 break;
4926
4927 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
4928 case WLAN_REASON_DISASSOC_AP_BUSY:
4929 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
4930 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
4931 break;
4932
4933 case WLAN_REASON_PREV_AUTH_NOT_VALID:
4934 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
4935 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
4936 break;
4937
4938 case WLAN_REASON_DEAUTH_LEAVING:
4939 default:
4940 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
4941 break;
4942 }
4943 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
4944 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
4945 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4946
4947 /*issue disconnect*/
4948 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4949 pAdapter->sessionId, reasonCode);
4950
4951 if ( 0 != status)
4952 {
4953 hddLog(VOS_TRACE_LEVEL_ERROR,
4954 "%s csrRoamDisconnect failure, returned %d \n",
4955 __func__, (int)status );
4956 return -EINVAL;
4957 }
4958
4959 wait_for_completion_interruptible_timeout(
4960 &pAdapter->disconnect_comp_var,
4961 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4962
4963
4964 /*stop tx queues*/
4965 netif_tx_disable(dev);
4966 netif_carrier_off(dev);
4967 }
4968 }
4969 else
4970 {
4971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
4972 }
4973
4974 return status;
4975}
4976
4977/*
4978 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
4979 * This function is used to initialize the security
4980 * settings in IBSS mode.
4981 */
4982static int wlan_hdd_cfg80211_set_privacy_ibss(
4983 hdd_adapter_t *pAdapter,
4984 struct cfg80211_ibss_params *params
4985 )
4986{
4987 int status = 0;
4988 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4989 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4990 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4991
4992 ENTER();
4993
4994 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4995
4996 if (params->ie_len && ( NULL != params->ie) )
4997 {
4998 if (WLAN_EID_RSN == params->ie[0])
4999 {
5000 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5001 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5002 }
5003 else
5004 {
5005 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5006 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5007 }
5008 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5009
5010 if (0 > status)
5011 {
5012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5013 __func__);
5014 return status;
5015 }
5016 }
5017
5018 pWextState->roamProfile.AuthType.authType[0] =
5019 pHddStaCtx->conn_info.authType =
5020 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5021
5022 if (params->privacy)
5023 {
5024 /* Security enabled IBSS, At this time there is no information available
5025 * about the security paramters, so initialise the encryption type to
5026 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5027 * The correct security parameters will be updated later in
5028 * wlan_hdd_cfg80211_add_key */
5029 /* Hal expects encryption type to be set inorder
5030 *enable privacy bit in beacons */
5031
5032 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5033 }
5034
5035 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5036 pWextState->roamProfile.EncryptionType.numEntries = 1;
5037 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5038
5039 return status;
5040}
5041
5042/*
5043 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5044 * This function is used to create/join an IBSS
5045 */
5046static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5047 struct net_device *dev,
5048 struct cfg80211_ibss_params *params
5049 )
5050{
5051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5052 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5053 tCsrRoamProfile *pRoamProfile;
5054 int status;
5055 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5056
5057 ENTER();
5058
5059 hddLog(VOS_TRACE_LEVEL_INFO,
5060 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5061
5062 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5063 {
5064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5065 "%s:LOGP in Progress. Ignore!!!", __func__);
5066 return -EAGAIN;
5067 }
5068
5069 if (NULL == pWextState)
5070 {
5071 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5072 __func__);
5073 return -EIO;
5074 }
5075
5076 pRoamProfile = &pWextState->roamProfile;
5077
5078 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5079 {
5080 hddLog (VOS_TRACE_LEVEL_ERROR,
5081 "%s Interface type is not set to IBSS \n", __func__);
5082 return -EINVAL;
5083 }
5084
5085 /* Set Channel */
5086 if (NULL != params->channel)
5087 {
5088 u8 channelNum;
5089 if (IEEE80211_BAND_5GHZ == params->channel->band)
5090 {
5091 hddLog(VOS_TRACE_LEVEL_ERROR,
5092 "%s: IBSS join is called with unsupported band %d",
5093 __func__, params->channel->band);
5094 return -EOPNOTSUPP;
5095 }
5096
5097 /* Get channel number */
5098 channelNum =
5099 ieee80211_frequency_to_channel(params->channel->center_freq);
5100
5101 /*TODO: use macro*/
5102 if (14 >= channelNum)
5103 {
5104 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5105 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5106 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5107 int indx;
5108
5109 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5110 validChan, &numChans))
5111 {
5112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5113 __func__);
5114 return -EOPNOTSUPP;
5115 }
5116
5117 for (indx = 0; indx < numChans; indx++)
5118 {
5119 if (channelNum == validChan[indx])
5120 {
5121 break;
5122 }
5123 }
5124 if (indx >= numChans)
5125 {
5126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5127 __func__, channelNum);
5128 return -EINVAL;
5129 }
5130 /* Set the Operational Channel */
5131 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5132 channelNum);
5133 pRoamProfile->ChannelInfo.numOfChannels = 1;
5134 pHddStaCtx->conn_info.operationChannel = channelNum;
5135 pRoamProfile->ChannelInfo.ChannelList =
5136 &pHddStaCtx->conn_info.operationChannel;
5137 }
5138 else
5139 {
5140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5141 __func__, channelNum);
5142 return -EINVAL;
5143 }
5144 }
5145
5146 /* Initialize security parameters */
5147 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5148 if (status < 0)
5149 {
5150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5151 __func__);
5152 return status;
5153 }
5154
5155 /* Issue connect start */
5156 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005157 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005158
5159 if (0 > status)
5160 {
5161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5162 return status;
5163 }
5164
5165 return 0;
5166}
5167
5168/*
5169 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5170 * This function is used to leave an IBSS
5171 */
5172static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5173 struct net_device *dev
5174 )
5175{
5176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5177 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5178 tCsrRoamProfile *pRoamProfile;
5179
5180 ENTER();
5181
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005182 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5183 {
5184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5185 "%s:LOGP in Progress. Ignore!!!", __func__);
5186 return -EAGAIN;
5187 }
5188
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5190 if (NULL == pWextState)
5191 {
5192 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5193 __func__);
5194 return -EIO;
5195 }
5196
5197 pRoamProfile = &pWextState->roamProfile;
5198
5199 /* Issue disconnect only if interface type is set to IBSS */
5200 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5201 {
5202 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5203 __func__);
5204 return -EINVAL;
5205 }
5206
5207 /* Issue Disconnect request */
5208 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5209 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5210 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5211
5212 return 0;
5213}
5214
5215/*
5216 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5217 * This function is used to set the phy parameters
5218 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5219 */
5220static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5221 u32 changed)
5222{
5223 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5224 tHalHandle hHal = pHddCtx->hHal;
5225
5226 ENTER();
5227
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005228 if ( pHddCtx->isLogpInProgress )
5229 {
5230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5231 "%s:LOGP in Progress. Ignore!!!", __func__);
5232 return -EAGAIN;
5233 }
5234
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5236 {
5237 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5238 WNI_CFG_RTS_THRESHOLD_STAMAX :
5239 wiphy->rts_threshold;
5240
5241 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5242 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5243 {
5244 hddLog(VOS_TRACE_LEVEL_ERROR,
5245 "%s: Invalid RTS Threshold value %hu",
5246 __func__, rts_threshold);
5247 return -EINVAL;
5248 }
5249
5250 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5251 rts_threshold, ccmCfgSetCallback,
5252 eANI_BOOLEAN_TRUE))
5253 {
5254 hddLog(VOS_TRACE_LEVEL_ERROR,
5255 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5256 __func__, rts_threshold);
5257 return -EIO;
5258 }
5259
5260 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5261 rts_threshold);
5262 }
5263
5264 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5265 {
5266 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5267 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5268 wiphy->frag_threshold;
5269
5270 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5271 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5272 {
5273 hddLog(VOS_TRACE_LEVEL_ERROR,
5274 "%s: Invalid frag_threshold value %hu", __func__,
5275 frag_threshold);
5276 return -EINVAL;
5277 }
5278
5279 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5280 frag_threshold, ccmCfgSetCallback,
5281 eANI_BOOLEAN_TRUE))
5282 {
5283 hddLog(VOS_TRACE_LEVEL_ERROR,
5284 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5285 __func__, frag_threshold);
5286 return -EIO;
5287 }
5288
5289 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5290 frag_threshold);
5291 }
5292
5293 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5294 || (changed & WIPHY_PARAM_RETRY_LONG))
5295 {
5296 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5297 wiphy->retry_short :
5298 wiphy->retry_long;
5299
5300 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5301 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5302 {
5303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5304 __func__, retry_value);
5305 return -EINVAL;
5306 }
5307
5308 if (changed & WIPHY_PARAM_RETRY_SHORT)
5309 {
5310 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5311 retry_value, ccmCfgSetCallback,
5312 eANI_BOOLEAN_TRUE))
5313 {
5314 hddLog(VOS_TRACE_LEVEL_ERROR,
5315 "%s: ccmCfgSetInt failed for long retry count %hu",
5316 __func__, retry_value);
5317 return -EIO;
5318 }
5319 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5320 __func__, retry_value);
5321 }
5322 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5323 {
5324 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5325 retry_value, ccmCfgSetCallback,
5326 eANI_BOOLEAN_TRUE))
5327 {
5328 hddLog(VOS_TRACE_LEVEL_ERROR,
5329 "%s: ccmCfgSetInt failed for short retry count %hu",
5330 __func__, retry_value);
5331 return -EIO;
5332 }
5333 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5334 __func__, retry_value);
5335 }
5336 }
5337
5338 return 0;
5339}
5340
5341/*
5342 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5343 * This function is used to set the txpower
5344 */
5345static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5346#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5347 enum tx_power_setting type,
5348#else
5349 enum nl80211_tx_power_setting type,
5350#endif
5351 int dbm)
5352{
5353 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5354 tHalHandle hHal = pHddCtx->hHal;
5355 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5356 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5357
5358 ENTER();
5359
5360 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5361 dbm, ccmCfgSetCallback,
5362 eANI_BOOLEAN_TRUE))
5363 {
5364 hddLog(VOS_TRACE_LEVEL_ERROR,
5365 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5366 return -EIO;
5367 }
5368
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005369 if ( pHddCtx->isLogpInProgress )
5370 {
5371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5372 "%s:LOGP in Progress. Ignore!!!", __func__);
5373 return -EAGAIN;
5374 }
5375
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5377 dbm);
5378
5379 switch(type)
5380 {
5381 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5382 /* Fall through */
5383 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5384 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5385 {
5386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5387 __func__);
5388 return -EIO;
5389 }
5390 break;
5391 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5393 __func__);
5394 return -EOPNOTSUPP;
5395 break;
5396 default:
5397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5398 __func__, type);
5399 return -EIO;
5400 }
5401
5402 return 0;
5403}
5404
5405/*
5406 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5407 * This function is used to read the txpower
5408 */
5409static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5410{
5411
5412 hdd_adapter_t *pAdapter;
5413 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5414
Jeff Johnsone7245742012-09-05 17:12:55 -07005415 ENTER();
5416
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 if (NULL == pHddCtx)
5418 {
5419 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5420 *dbm = 0;
5421 return -ENOENT;
5422 }
5423
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005424 if ( pHddCtx->isLogpInProgress )
5425 {
5426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5427 "%s:LOGP in Progress. Ignore!!!", __func__);
5428 return -EAGAIN;
5429 }
5430
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5432 if (NULL == pAdapter)
5433 {
5434 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5435 return -ENOENT;
5436 }
5437
5438 wlan_hdd_get_classAstats(pAdapter);
5439 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5440
Jeff Johnsone7245742012-09-05 17:12:55 -07005441 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 return 0;
5443}
5444
5445static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5446 u8* mac, struct station_info *sinfo)
5447{
5448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5449 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5450 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5451 tANI_U8 rate_flags;
5452
5453 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5454 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5455 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5456
5457 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5458 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5459 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5460 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5461 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5462 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5463 tANI_U16 maxRate = 0;
5464 tANI_U16 myRate;
5465 tANI_U16 currentRate = 0;
5466 tANI_U8 maxSpeedMCS = 0;
5467 tANI_U8 maxMCSIdx = 0;
5468 tANI_U8 rateFlag = 1;
5469 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005470 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005471
Jeff Johnsone7245742012-09-05 17:12:55 -07005472 ENTER();
5473
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5475 (0 == ssidlen))
5476 {
5477 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5478 " Invalid ssidlen, %d", __func__, ssidlen);
5479 /*To keep GUI happy*/
5480 return 0;
5481 }
5482
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005483 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5484 {
5485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5486 "%s:LOGP in Progress. Ignore!!!", __func__);
5487 return -EAGAIN;
5488 }
5489
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5491 sinfo->filled |= STATION_INFO_SIGNAL;
5492
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005493 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5495
5496 //convert to the UI units of 100kbps
5497 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5498
5499#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005500 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 -07005501 sinfo->signal,
5502 pCfg->reportMaxLinkSpeed,
5503 myRate,
5504 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005505 (int) pCfg->linkSpeedRssiMid,
5506 (int) pCfg->linkSpeedRssiLow,
5507 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005508#endif //LINKSPEED_DEBUG_ENABLED
5509
5510 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5511 {
5512 // we do not want to necessarily report the current speed
5513 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5514 {
5515 // report the max possible speed
5516 rssidx = 0;
5517 }
5518 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5519 {
5520 // report the max possible speed with RSSI scaling
5521 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5522 {
5523 // report the max possible speed
5524 rssidx = 0;
5525 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005526 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 {
5528 // report middle speed
5529 rssidx = 1;
5530 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005531 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5532 {
5533 // report middle speed
5534 rssidx = 2;
5535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 else
5537 {
5538 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005539 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 }
5541 }
5542 else
5543 {
5544 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5545 hddLog(VOS_TRACE_LEVEL_ERROR,
5546 "%s: Invalid value for reportMaxLinkSpeed: %u",
5547 __func__, pCfg->reportMaxLinkSpeed);
5548 rssidx = 0;
5549 }
5550
5551 maxRate = 0;
5552
5553 /* Get Basic Rate Set */
5554 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5555 for (i = 0; i < ORLeng; i++)
5556 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005557 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 {
5559 /* Validate Rate Set */
5560 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5561 {
5562 currentRate = supported_data_rate[j].supported_rate[rssidx];
5563 break;
5564 }
5565 }
5566 /* Update MAX rate */
5567 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5568 }
5569
5570 /* Get Extended Rate Set */
5571 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5572 for (i = 0; i < ERLeng; i++)
5573 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005574 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 {
5576 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
5577 {
5578 currentRate = supported_data_rate[j].supported_rate[rssidx];
5579 break;
5580 }
5581 }
5582 /* Update MAX rate */
5583 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5584 }
5585
5586 /* Get MCS Rate Set -- but only if we are connected at MCS
5587 rates or if we are always reporting max speed or if we have
5588 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005589 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 {
5591 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
5592 rateFlag = 0;
5593 if (rate_flags & eHAL_TX_RATE_HT40)
5594 {
5595 rateFlag |= 1;
5596 }
5597 if (rate_flags & eHAL_TX_RATE_SGI)
5598 {
5599 rateFlag |= 2;
5600 }
5601
5602 for (i = 0; i < MCSLeng; i++)
5603 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005604 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
5605 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 {
5607 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
5608 {
5609 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
5610 break;
5611 }
5612 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005613 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 {
5615 maxRate = currentRate;
5616 maxSpeedMCS = 1;
5617 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
5618 }
5619 }
5620 }
5621
5622 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005623 if (((maxRate < myRate) && (0 == rssidx)) ||
5624 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 {
5626 maxRate = myRate;
5627 if (rate_flags & eHAL_TX_RATE_LEGACY)
5628 {
5629 maxSpeedMCS = 0;
5630 }
5631 else
5632 {
5633 maxSpeedMCS = 1;
5634 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5635 }
5636 }
5637
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005638 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 {
5640 sinfo->txrate.legacy = maxRate;
5641#ifdef LINKSPEED_DEBUG_ENABLED
5642 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
5643#endif //LINKSPEED_DEBUG_ENABLED
5644 }
5645 else
5646 {
5647 sinfo->txrate.mcs = maxMCSIdx;
5648 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5649 if (rate_flags & eHAL_TX_RATE_SGI)
5650 {
5651 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5652 }
5653 if (rate_flags & eHAL_TX_RATE_HT40)
5654 {
5655 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5656 }
5657#ifdef LINKSPEED_DEBUG_ENABLED
5658 pr_info("Reporting MCS rate %d flags %x\n",
5659 sinfo->txrate.mcs,
5660 sinfo->txrate.flags );
5661#endif //LINKSPEED_DEBUG_ENABLED
5662 }
5663 }
5664 else
5665 {
5666 // report current rate instead of max rate
5667
5668 if (rate_flags & eHAL_TX_RATE_LEGACY)
5669 {
5670 //provide to the UI in units of 100kbps
5671 sinfo->txrate.legacy = myRate;
5672#ifdef LINKSPEED_DEBUG_ENABLED
5673 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
5674#endif //LINKSPEED_DEBUG_ENABLED
5675 }
5676 else
5677 {
5678 //must be MCS
5679 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5680 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5681 if (rate_flags & eHAL_TX_RATE_SGI)
5682 {
5683 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5684 }
5685 if (rate_flags & eHAL_TX_RATE_HT40)
5686 {
5687 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5688 }
5689#ifdef LINKSPEED_DEBUG_ENABLED
5690 pr_info("Reporting actual MCS rate %d flags %x\n",
5691 sinfo->txrate.mcs,
5692 sinfo->txrate.flags );
5693#endif //LINKSPEED_DEBUG_ENABLED
5694 }
5695 }
5696 sinfo->filled |= STATION_INFO_TX_BITRATE;
5697
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005698 sinfo->tx_packets =
5699 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
5700 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
5701 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
5702 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
5703
5704 sinfo->tx_retries =
5705 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
5706 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
5707 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
5708 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
5709
5710 sinfo->tx_failed =
5711 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
5712 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
5713 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
5714 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
5715
5716 sinfo->filled |=
5717 STATION_INFO_TX_PACKETS |
5718 STATION_INFO_TX_RETRIES |
5719 STATION_INFO_TX_FAILED;
5720
5721 EXIT();
5722 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005723}
5724
5725static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
5726 struct net_device *dev, bool mode, v_SINT_t timeout)
5727{
5728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5729 VOS_STATUS vos_status;
5730
Jeff Johnsone7245742012-09-05 17:12:55 -07005731 ENTER();
5732
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 if (NULL == pAdapter)
5734 {
5735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5736 return -ENODEV;
5737 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005738 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5739 {
5740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5741 "%s:LOGP in Progress. Ignore!!!", __func__);
5742 return -EAGAIN;
5743 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005744
5745 /**The get power cmd from the supplicant gets updated by the nl only
5746 *on successful execution of the function call
5747 *we are oppositely mapped w.r.t mode in the driver
5748 **/
5749 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
5750
Jeff Johnsone7245742012-09-05 17:12:55 -07005751 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 if (VOS_STATUS_E_FAILURE == vos_status)
5753 {
5754 return -EINVAL;
5755 }
5756 return 0;
5757}
5758
5759
5760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5761static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
5762 struct net_device *netdev,
5763 u8 key_index)
5764{
Jeff Johnsone7245742012-09-05 17:12:55 -07005765 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 return 0;
5767}
5768#endif //LINUX_VERSION_CODE
5769
5770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5771static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5772 struct net_device *dev,
5773 struct ieee80211_txq_params *params)
5774{
Jeff Johnsone7245742012-09-05 17:12:55 -07005775 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 return 0;
5777}
5778#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5779static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5780 struct ieee80211_txq_params *params)
5781{
Jeff Johnsone7245742012-09-05 17:12:55 -07005782 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 return 0;
5784}
5785#endif //LINUX_VERSION_CODE
5786
5787static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
5788 struct net_device *dev, u8 *mac)
5789{
5790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5791
Jeff Johnsone7245742012-09-05 17:12:55 -07005792 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
5794 {
5795 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
5796 return -EINVAL;
5797 }
5798
5799 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
5800 {
5801 hddLog( LOGE,
5802 "%s: Wlan Load/Unload is in progress", __func__);
5803 return -EBUSY;
5804 }
5805
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005806 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5807 {
5808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5809 "%s:LOGP in Progress. Ignore!!!", __func__);
5810 return -EAGAIN;
5811 }
5812
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
5814#ifdef WLAN_FEATURE_P2P
5815 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5816#endif
5817 )
5818 {
5819 if( NULL == mac )
5820 {
5821 v_U16_t i;
5822 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
5823 {
5824 if(pAdapter->aStaInfo[i].isUsed)
5825 {
5826 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
5827 hddLog(VOS_TRACE_LEVEL_INFO,
5828 "%s: Delete STA with MAC::"
5829 "%02x:%02x:%02x:%02x:%02x:%02x",
5830 __func__,
5831 macAddr[0], macAddr[1], macAddr[2],
5832 macAddr[3], macAddr[4], macAddr[5]);
5833 hdd_softap_sta_deauth(pAdapter, macAddr);
5834 }
5835 }
5836 }
5837 else
5838 {
5839 hddLog(VOS_TRACE_LEVEL_INFO,
5840 "%s: Delete STA with MAC::"
5841 "%02x:%02x:%02x:%02x:%02x:%02x",
5842 __func__,
5843 mac[0], mac[1], mac[2],
5844 mac[3], mac[4], mac[5]);
5845 hdd_softap_sta_deauth(pAdapter, mac);
5846 }
5847 }
5848
5849 EXIT();
5850
5851 return 0;
5852}
5853
5854static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
5855 struct net_device *dev, u8 *mac, struct station_parameters *params)
5856{
5857 // TODO: Implement this later.
Jeff Johnsone7245742012-09-05 17:12:55 -07005858 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 return 0;
5860}
5861
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005862
5863#ifdef FEATURE_WLAN_LFR
5864static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07005865 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005866{
5867#define MAX_PMKSAIDS_IN_CACHE 8
5868 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07005869 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005870 tANI_U32 j=0;
5871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5872 tHalHandle halHandle;
5873 eHalStatus result;
5874 tANI_U8 BSSIDMatched = 0;
5875
Jeff Johnsone7245742012-09-05 17:12:55 -07005876 ENTER();
5877
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005878 // Validate pAdapter
5879 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
5880 {
5881 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
5882 return -EINVAL;
5883 }
5884
5885 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
5886 {
5887 hddLog( LOGE,
5888 "%s: Wlan Load/Unload is in progress", __func__);
5889 return -EBUSY;
5890 }
5891
5892 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5893 {
5894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5895 "%s:LOGP in Progress. Ignore!!!", __func__);
5896 return -EAGAIN;
5897 }
5898
5899 // Retrieve halHandle
5900 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5901
5902 for (j = 0; j < i; j++)
5903 {
5904 if(vos_mem_compare(PMKIDCache[j].BSSID,
5905 pmksa->bssid, WNI_CFG_BSSID_LEN))
5906 {
5907 /* BSSID matched previous entry. Overwrite it. */
5908 BSSIDMatched = 1;
5909 vos_mem_copy(PMKIDCache[j].BSSID,
5910 pmksa->bssid, WNI_CFG_BSSID_LEN);
5911 vos_mem_copy(PMKIDCache[j].PMKID,
5912 pmksa->pmkid,
5913 CSR_RSN_PMKID_SIZE);
5914 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005915 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005916 dump_bssid(pmksa->bssid);
5917 dump_pmkid(halHandle, pmksa->pmkid);
5918 break;
5919 }
5920 }
5921
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07005922 /* Check we compared all entries,if then take the first slot now */
5923 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
5924
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005925 if (!BSSIDMatched)
5926 {
5927 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
5928 vos_mem_copy(PMKIDCache[i].BSSID,
5929 pmksa->bssid, ETHER_ADDR_LEN);
5930 vos_mem_copy(PMKIDCache[i].PMKID,
5931 pmksa->pmkid,
5932 CSR_RSN_PMKID_SIZE);
5933 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005934 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005935 dump_bssid(pmksa->bssid);
5936 dump_pmkid(halHandle, pmksa->pmkid);
5937 // Increment the HDD Local Cache index
5938 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
5939 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
5940 }
5941
5942
5943 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
5944 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005945 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005946 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005947 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005948 // Finally set the PMKSA ID Cache in CSR
5949 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
5950 PMKIDCache,
5951 i );
5952 return 0;
5953}
5954
5955
5956static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07005957 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005958{
Jeff Johnsone7245742012-09-05 17:12:55 -07005959 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005960 // TODO: Implement this later.
5961 return 0;
5962}
5963
5964static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
5965{
Jeff Johnsone7245742012-09-05 17:12:55 -07005966 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005967 // TODO: Implement this later.
5968 return 0;
5969}
5970#endif
5971
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005972#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
5973static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
5974 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
5975{
5976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5977 hdd_station_ctx_t *pHddStaCtx;
5978
5979 if (NULL == pAdapter)
5980 {
5981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5982 return -ENODEV;
5983 }
5984
5985 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5986
5987 // Added for debug on reception of Re-assoc Req.
5988 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5989 {
5990 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
5991 ftie->ie_len);
5992 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
5993 }
5994
5995#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
5996 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
5997 ftie->ie_len);
5998#endif
5999
6000 // Pass the received FT IEs to SME
6001 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6002 ftie->ie_len);
6003 return 0;
6004}
6005#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006006
Jeff Johnson295189b2012-06-20 16:38:30 -07006007/* cfg80211_ops */
6008static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6009{
6010 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6011 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6012 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6013 .change_station = wlan_hdd_change_station,
6014#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6015 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6016 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6017 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006018#else
6019 .start_ap = wlan_hdd_cfg80211_start_ap,
6020 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6021 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006022#endif
6023 .change_bss = wlan_hdd_cfg80211_change_bss,
6024 .add_key = wlan_hdd_cfg80211_add_key,
6025 .get_key = wlan_hdd_cfg80211_get_key,
6026 .del_key = wlan_hdd_cfg80211_del_key,
6027 .set_default_key = wlan_hdd_cfg80211_set_default_key,
6028 .set_channel = wlan_hdd_cfg80211_set_channel,
6029 .scan = wlan_hdd_cfg80211_scan,
6030 .connect = wlan_hdd_cfg80211_connect,
6031 .disconnect = wlan_hdd_cfg80211_disconnect,
6032 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6033 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6034 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6035 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6036 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6037#ifdef WLAN_FEATURE_P2P
6038 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6039 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6040 .mgmt_tx = wlan_hdd_action,
6041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6042 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6043 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6044 .set_txq_params = wlan_hdd_set_txq_params,
6045#endif
6046#endif
6047 .get_station = wlan_hdd_cfg80211_get_station,
6048 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6049 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006050 .add_station = wlan_hdd_cfg80211_add_station,
6051#ifdef FEATURE_WLAN_LFR
6052 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6053 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6054 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6055#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006056#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6057 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6058#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006059};
6060
6061#endif // CONFIG_CFG80211