blob: db5f0d6f960b6bc8cd570d321e50c664b9ad51c8 [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{
1239 tsap_Config_t *pConfig;
1240 beacon_data_t *pBeacon = NULL;
1241 struct ieee80211_mgmt *pMgmt_frame;
1242 v_U8_t *pIe=NULL;
1243 v_U16_t capab_info;
1244 eCsrAuthType RSNAuthType;
1245 eCsrEncryptionType RSNEncryptType;
1246 eCsrEncryptionType mcRSNEncryptType;
1247 int status = VOS_STATUS_SUCCESS;
1248 tpWLAN_SAPEventCB pSapEventCallback;
1249 hdd_hostapd_state_t *pHostapdState;
1250 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1251 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1252 struct qc_mac_acl_entry *acl_entry = NULL;
1253 v_SINT_t i;
1254
1255 ENTER();
1256
1257 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1258
1259 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1260
1261 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1262
1263 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1264
1265 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1266
1267 //channel is already set in the set_channel Call back
1268 //pConfig->channel = pCommitConfig->channel;
1269
1270 /*Protection parameter to enable or disable*/
1271 pConfig->protEnabled =
1272 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1273
1274 pConfig->dtim_period = pBeacon->dtim_period;
1275
1276 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1277 pConfig->dtim_period);
1278
1279
Jeff Johnson32d95a32012-09-10 13:15:23 -07001280 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
1281 {
1282 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001283 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001284 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001285 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001286 tANI_BOOLEAN restartNeeded;
1287 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1288 pConfig->ieee80211d = 1;
1289 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1290 sme_setRegInfo(hHal, pConfig->countryCode);
1291 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1292 /*
1293 * If auto channel is configured i.e. channel is 0,
1294 * so skip channel validation.
1295 */
1296 if( AUTO_CHANNEL_SELECT != pConfig->channel )
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001298 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1299 {
1300 hddLog(VOS_TRACE_LEVEL_ERROR,
1301 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1302 return -EINVAL;
1303 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001304 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001305 /*
1306 * Validate the given channel range for the given country code
1307 */
1308 else
1309 {
1310 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1311 WLANSAP_SetChannelRange(hHal,hdd_pConfig->apStartChannelNum,hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1312 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001313 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001314 else
1315 {
1316 pConfig->ieee80211d = 0;
1317 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001318 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001319 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001320 {
1321 pConfig->ieee80211d = 0;
1322 }
1323 pConfig->authType = eSAP_AUTO_SWITCH;
1324
1325 capab_info = pMgmt_frame->u.beacon.capab_info;
1326
1327 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1328 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1329
1330 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1331
1332 /*Set wps station to configured*/
1333 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1334
1335 if(pIe)
1336 {
1337 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1338 {
1339 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1340 return -EINVAL;
1341 }
1342 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1343 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001344 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001345 /* Check 15 bit of WPS IE as it contain information for wps state
1346 * WPS state
1347 */
1348 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1349 {
1350 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1351 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1352 {
1353 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1354 }
1355 }
1356 }
1357 else
1358 {
1359 pConfig->wps_state = SAP_WPS_DISABLED;
1360 }
1361 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1362
1363 pConfig->RSNWPAReqIELength = 0;
1364 pConfig->pRSNWPAReqIE = NULL;
1365 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1366 WLAN_EID_RSN);
1367 if(pIe && pIe[1])
1368 {
1369 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1370 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1371 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1372 /* The actual processing may eventually be more extensive than
1373 * this. Right now, just consume any PMKIDs that are sent in
1374 * by the app.
1375 * */
1376 status = hdd_softap_unpackIE(
1377 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1378 &RSNEncryptType,
1379 &mcRSNEncryptType,
1380 &RSNAuthType,
1381 pConfig->pRSNWPAReqIE[1]+2,
1382 pConfig->pRSNWPAReqIE );
1383
1384 if( VOS_STATUS_SUCCESS == status )
1385 {
1386 /* Now copy over all the security attributes you have
1387 * parsed out
1388 * */
1389 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1390 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1391 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1392 = RSNEncryptType;
1393 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1394 "EncryptionType = %d mcEncryptionType = %d\n"),
1395 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1396 }
1397 }
1398
1399 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1400 pBeacon->tail, pBeacon->tail_len);
1401
1402 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1403 {
1404 if (pConfig->pRSNWPAReqIE)
1405 {
1406 /*Mixed mode WPA/WPA2*/
1407 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1408 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1409 }
1410 else
1411 {
1412 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1413 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1414 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1415 status = hdd_softap_unpackIE(
1416 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1417 &RSNEncryptType,
1418 &mcRSNEncryptType,
1419 &RSNAuthType,
1420 pConfig->pRSNWPAReqIE[1]+2,
1421 pConfig->pRSNWPAReqIE );
1422
1423 if( VOS_STATUS_SUCCESS == status )
1424 {
1425 /* Now copy over all the security attributes you have
1426 * parsed out
1427 * */
1428 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1429 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1430 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1431 = RSNEncryptType;
1432 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1433 "EncryptionType = %d mcEncryptionType = %d\n"),
1434 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1435 }
1436 }
1437 }
1438
1439 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1440
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001441#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001442 if (params->ssid != NULL)
1443 {
1444 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1445 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1446 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1447 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1448 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001449#else
1450 if (ssid != NULL)
1451 {
1452 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1453 pConfig->SSIDinfo.ssid.length = ssid_len;
1454 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1455 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1456 }
1457#endif
1458
Jeff Johnson295189b2012-06-20 16:38:30 -07001459 vos_mem_copy(pConfig->self_macaddr.bytes,
1460 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1461
1462 /* default value */
1463 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1464 pConfig->num_accept_mac = 0;
1465 pConfig->num_deny_mac = 0;
1466
1467 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1468 pBeacon->tail, pBeacon->tail_len);
1469
1470 /* pIe for black list is following form:
1471 type : 1 byte
1472 length : 1 byte
1473 OUI : 4 bytes
1474 acl type : 1 byte
1475 no of mac addr in black list: 1 byte
1476 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1477 */
1478 if ((pIe != NULL) && (pIe[1] != 0))
1479 {
1480 pConfig->SapMacaddr_acl = pIe[6];
1481 pConfig->num_deny_mac = pIe[7];
1482 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1483 pIe[6], pIe[7]);
1484 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1485 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1486 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1487 for (i = 0; i < pConfig->num_deny_mac; i++)
1488 {
1489 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1490 acl_entry++;
1491 }
1492 }
1493 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1494 pBeacon->tail, pBeacon->tail_len);
1495
1496 /* pIe for white list is following form:
1497 type : 1 byte
1498 length : 1 byte
1499 OUI : 4 bytes
1500 acl type : 1 byte
1501 no of mac addr in white list: 1 byte
1502 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1503 */
1504 if ((pIe != NULL) && (pIe[1] != 0))
1505 {
1506 pConfig->SapMacaddr_acl = pIe[6];
1507 pConfig->num_accept_mac = pIe[7];
1508 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1509 pIe[6], pIe[7]);
1510 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1511 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1512 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1513 for (i = 0; i < pConfig->num_accept_mac; i++)
1514 {
1515 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1516 acl_entry++;
1517 }
1518 }
1519 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1520
Jeff Johnsone7245742012-09-05 17:12:55 -07001521#ifdef WLAN_FEATURE_11AC
1522 if(((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1523 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1524 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) )
1525 {
1526 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1527 }
1528#endif
1529
Jeff Johnson295189b2012-06-20 16:38:30 -07001530 // ht_capab is not what the name conveys,this is used for protection bitmap
1531 pConfig->ht_capab =
1532 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1533
1534 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1535 {
1536 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1537 return -EINVAL;
1538 }
1539
1540 //Uapsd Enabled Bit
1541 pConfig->UapsdEnable =
1542 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1543 //Enable OBSS protection
1544 pConfig->obssProtEnabled =
1545 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1546
1547 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1548 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1549 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1550 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1551 (int)pConfig->channel);
1552 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1553 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1554 pConfig->authType);
1555 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1556 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1557 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1558 pConfig->protEnabled, pConfig->obssProtEnabled);
1559
1560 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1561 {
1562 //Bss already started. just return.
1563 //TODO Probably it should update some beacon params.
1564 hddLog( LOGE, "Bss Already started...Ignore the request");
1565 EXIT();
1566 return 0;
1567 }
1568
1569 pConfig->persona = pHostapdAdapter->device_mode;
1570
1571 pSapEventCallback = hdd_hostapd_SAPEventCB;
1572 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1573 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1574 {
1575 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1576 return -EINVAL;
1577 }
1578
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001579 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1581
1582 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1583
1584 if (!VOS_IS_STATUS_SUCCESS(status))
1585 {
1586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1587 ("ERROR: HDD vos wait for single_event failed!!\n"));
1588 VOS_ASSERT(0);
1589 }
1590
1591 //Succesfully started Bss update the state bit.
1592 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1593
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001594#ifdef WLAN_FEATURE_P2P_DEBUG
1595 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1596 {
1597 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1598 {
1599 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1600 hddLog(LOGE,"[P2P State] From Go nego completed to "
1601 "Non-autonomus Group started");
1602 }
1603 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1604 {
1605 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1606 hddLog(LOGE,"[P2P State] From Inactive to "
1607 "Autonomus Group started");
1608 }
1609 }
1610#endif
1611
Jeff Johnson295189b2012-06-20 16:38:30 -07001612 pHostapdState->bCommit = TRUE;
1613 EXIT();
1614
1615 return 0;
1616}
1617
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001618#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001619static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1620 struct net_device *dev,
1621 struct beacon_parameters *params)
1622{
1623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1624 int status=VOS_STATUS_SUCCESS;
1625
1626 ENTER();
1627
1628 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1629
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001630 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1631 {
1632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1633 "%s:LOGP in Progress. Ignore!!!", __func__);
1634 return -EAGAIN;
1635 }
1636
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1638#ifdef WLAN_FEATURE_P2P
1639 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1640#endif
1641 )
1642 {
1643 beacon_data_t *old,*new;
1644
1645 old = pAdapter->sessionCtx.ap.beacon;
1646
1647 if (old)
1648 return -EALREADY;
1649
1650 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1651
1652 if(status != VOS_STATUS_SUCCESS)
1653 {
1654 hddLog(VOS_TRACE_LEVEL_FATAL,
1655 "%s:Error!!! Allocating the new beacon\n",__func__);
1656 return -EINVAL;
1657 }
1658
1659 pAdapter->sessionCtx.ap.beacon = new;
1660
1661 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1662 }
1663
1664 EXIT();
1665 return status;
1666}
1667
1668static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
1669 struct net_device *dev,
1670 struct beacon_parameters *params)
1671{
1672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1673 int status=VOS_STATUS_SUCCESS;
1674
1675 ENTER();
1676
1677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1678 __func__,pAdapter->device_mode);
1679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001680 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1681 {
1682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1683 "%s:LOGP in Progress. Ignore!!!", __func__);
1684 return -EAGAIN;
1685 }
1686
Jeff Johnson295189b2012-06-20 16:38:30 -07001687 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1688#ifdef WLAN_FEATURE_P2P
1689 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1690#endif
1691 )
1692 {
1693 beacon_data_t *old,*new;
1694
1695 old = pAdapter->sessionCtx.ap.beacon;
1696
1697 if (!old)
1698 return -ENOENT;
1699
1700 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1701
1702 if(status != VOS_STATUS_SUCCESS) {
1703 hddLog(VOS_TRACE_LEVEL_FATAL,
1704 "%s: Error!!! Allocating the new beacon\n",__func__);
1705 return -EINVAL;
1706 }
1707
1708 pAdapter->sessionCtx.ap.beacon = new;
1709
1710 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1711 }
1712
1713 EXIT();
1714 return status;
1715}
1716
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001717#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1718
1719#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001720static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
1721 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001722#else
1723static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
1724 struct net_device *dev)
1725#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001726{
1727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001728 hdd_context_t *pHddCtx = NULL;
1729 hdd_scaninfo_t *pScanInfo = NULL;
1730 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 VOS_STATUS status = 0;
1732
1733 ENTER();
1734
1735 if (NULL == pAdapter)
1736 {
1737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001738 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 return -ENODEV;
1740 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001741 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1742 {
1743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1744 "%s:LOGP in Progress. Ignore!!!", __func__);
1745 return -EAGAIN;
1746 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001747
1748 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1749 if (NULL == pHddCtx)
1750 {
1751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001752 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001753 return -ENODEV;
1754 }
1755
1756 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
1757 if (NULL == staAdapter)
1758 {
1759 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
1760 if (NULL == staAdapter)
1761 {
1762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001763 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001764 return -ENODEV;
1765 }
1766 }
1767
1768 pScanInfo = &pHddCtx->scan_info;
1769
Jeff Johnson295189b2012-06-20 16:38:30 -07001770 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1771 {
1772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1773 return -EAGAIN;
1774 }
1775
1776 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1777
1778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1779 __func__,pAdapter->device_mode);
1780
Jeff Johnsone7245742012-09-05 17:12:55 -07001781 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
1782 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001783 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07001784 hdd_abort_mac_scan(staAdapter->pHddCtx);
1785 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001786 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07001787 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
1788 if (!status)
1789 {
1790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1791 "%s: Timeout occured while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001792 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001793 VOS_ASSERT(pScanInfo->mScanPending);
1794 return 0;
1795 }
1796 }
1797
Jeff Johnson295189b2012-06-20 16:38:30 -07001798 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1799#ifdef WLAN_FEATURE_P2P
1800 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1801#endif
1802 )
1803 {
1804 beacon_data_t *old;
1805
1806 old = pAdapter->sessionCtx.ap.beacon;
1807
1808 if (!old)
1809 return -ENOENT;
1810
1811#ifdef CONFIG_CFG80211
1812 hdd_cleanup_actionframe(pHddCtx, pAdapter);
1813#endif
1814
1815 mutex_lock(&pHddCtx->sap_lock);
1816 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
1817 {
1818 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
1819 {
1820 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1821
1822 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1823
1824 if (!VOS_IS_STATUS_SUCCESS(status))
1825 {
1826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1827 ("ERROR: HDD vos wait for single_event failed!!\n"));
1828 VOS_ASSERT(0);
1829 }
1830 }
1831 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
1832 }
1833 mutex_unlock(&pHddCtx->sap_lock);
1834
1835 if(status != VOS_STATUS_SUCCESS)
1836 {
1837 hddLog(VOS_TRACE_LEVEL_FATAL,
1838 "%s:Error!!! Stopping the BSS\n",__func__);
1839 return -EINVAL;
1840 }
1841
1842 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1843 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
1844 ==eHAL_STATUS_FAILURE)
1845 {
1846 hddLog(LOGE,
1847 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
1848 }
1849
1850 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1851 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1852 eANI_BOOLEAN_FALSE) )
1853 {
1854 hddLog(LOGE,
1855 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1856 }
1857
1858 // Reset WNI_CFG_PROBE_RSP Flags
1859 wlan_hdd_reset_prob_rspies(pAdapter);
1860
1861 pAdapter->sessionCtx.ap.beacon = NULL;
1862 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001863#ifdef WLAN_FEATURE_P2P_DEBUG
1864 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
1865 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
1866 {
1867 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
1868 "GO got removed");
1869 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
1870 }
1871#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001872 }
1873 EXIT();
1874 return status;
1875}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001876
1877#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
1878
1879static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
1880 struct net_device *dev,
1881 struct cfg80211_ap_settings *params)
1882{
1883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1884 int status = VOS_STATUS_SUCCESS;
1885
1886 ENTER();
1887
1888 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n", pAdapter->device_mode);
1889
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001890 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1891 {
1892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1893 return -EAGAIN;
1894 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001895 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1896#ifdef WLAN_FEATURE_P2P
1897 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1898#endif
1899 )
1900 {
1901 beacon_data_t *old,*new;
1902
1903 old = pAdapter->sessionCtx.ap.beacon;
1904
1905 if (old)
1906 return -EALREADY;
1907
1908 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
1909
1910 if(status != VOS_STATUS_SUCCESS)
1911 {
1912 hddLog(VOS_TRACE_LEVEL_FATAL,
1913 "%s:Error!!! Allocating the new beacon\n",__func__);
1914 return -EINVAL;
1915 }
1916 pAdapter->sessionCtx.ap.beacon = new;
1917 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
1918 params->ssid_len, params->hidden_ssid);
1919 }
1920
1921 EXIT();
1922 return status;
1923}
1924
1925
1926static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
1927 struct net_device *dev,
1928 struct cfg80211_beacon_data *params)
1929{
1930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1931 int status=VOS_STATUS_SUCCESS;
1932
1933 ENTER();
1934
1935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1936 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001937 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1938 {
1939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1940 return -EAGAIN;
1941 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001942
1943 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1944#ifdef WLAN_FEATURE_P2P
1945 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1946#endif
1947 )
1948 {
1949 beacon_data_t *old,*new;
1950
1951 old = pAdapter->sessionCtx.ap.beacon;
1952
1953 if (!old)
1954 return -ENOENT;
1955
1956 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
1957
1958 if(status != VOS_STATUS_SUCCESS) {
1959 hddLog(VOS_TRACE_LEVEL_FATAL,
1960 "%s: Error!!! Allocating the new beacon\n",__func__);
1961 return -EINVAL;
1962 }
1963
1964 pAdapter->sessionCtx.ap.beacon = new;
1965
1966 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
1967 }
1968
1969 EXIT();
1970 return status;
1971}
1972
1973#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
1974
Jeff Johnson295189b2012-06-20 16:38:30 -07001975
1976static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
1977 struct net_device *dev,
1978 struct bss_parameters *params)
1979{
1980 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1981
1982 ENTER();
1983
1984 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1985 __func__,pAdapter->device_mode);
1986
1987 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1988#ifdef WLAN_FEATURE_P2P
1989 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1990#endif
1991 )
1992 {
1993 /* ap_isolate == -1 means that in change bss, upper layer doesn't
1994 * want to update this parameter */
1995 if (-1 != params->ap_isolate)
1996 {
1997 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
1998 }
1999 }
2000
2001 EXIT();
2002 return 0;
2003}
2004
2005/*
2006 * FUNCTION: wlan_hdd_cfg80211_change_iface
2007 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2008 */
2009int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2010 struct net_device *ndev,
2011 enum nl80211_iftype type,
2012 u32 *flags,
2013 struct vif_params *params
2014 )
2015{
2016 struct wireless_dev *wdev;
2017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2018 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002019 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 tCsrRoamProfile *pRoamProfile = NULL;
2021 eCsrRoamBssType LastBSSType;
2022 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2023 eMib_dot11DesiredBssType connectedBssType;
2024 VOS_STATUS status;
2025
2026 ENTER();
2027
2028 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2029 {
2030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2031 return -EAGAIN;
2032 }
2033
2034 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2035 __func__, pAdapter->device_mode);
2036
2037 wdev = ndev->ieee80211_ptr;
2038
2039#ifdef WLAN_BTAMP_FEATURE
2040 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2041 (NL80211_IFTYPE_ADHOC == type)||
2042 (NL80211_IFTYPE_AP == type)||
2043 (NL80211_IFTYPE_P2P_GO == type))
2044 {
2045 pHddCtx->isAmpAllowed = VOS_FALSE;
2046 // stop AMP traffic
2047 status = WLANBAP_StopAmp();
2048 if(VOS_STATUS_SUCCESS != status )
2049 {
2050 pHddCtx->isAmpAllowed = VOS_TRUE;
2051 hddLog(VOS_TRACE_LEVEL_FATAL,
2052 "%s: Failed to stop AMP", __func__);
2053 return -EINVAL;
2054 }
2055 }
2056#endif //WLAN_BTAMP_FEATURE
2057 /* Reset the current device mode bit mask*/
2058 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2059
2060 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2061#ifdef WLAN_FEATURE_P2P
2062 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002063 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002064#endif
2065 )
2066 {
2067 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2068 pRoamProfile = &pWextState->roamProfile;
2069 LastBSSType = pRoamProfile->BSSType;
2070
2071 switch (type)
2072 {
2073 case NL80211_IFTYPE_STATION:
2074#ifdef WLAN_FEATURE_P2P
2075 case NL80211_IFTYPE_P2P_CLIENT:
2076#endif
2077 hddLog(VOS_TRACE_LEVEL_INFO,
2078 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2079 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002080#ifdef WLAN_FEATURE_11AC
2081 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2082 {
2083 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2084 }
2085#endif
2086 pRoamProfile->phyMode =
2087 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002088 wdev->iftype = type;
2089#ifdef WLAN_FEATURE_P2P
2090 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2091 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
2092#endif
2093 break;
2094 case NL80211_IFTYPE_ADHOC:
2095 hddLog(VOS_TRACE_LEVEL_INFO,
2096 "%s: setting interface Type to ADHOC", __func__);
2097 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2098 pRoamProfile->phyMode =
2099 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2100 wdev->iftype = type;
2101 break;
2102
2103 case NL80211_IFTYPE_AP:
2104#ifdef WLAN_FEATURE_P2P
2105 case NL80211_IFTYPE_P2P_GO:
2106#endif
2107 {
2108 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2109 "%s: setting interface Type to %s", __func__,
2110 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2111
Mohit Khanna0f232092012-09-11 14:46:08 -07002112 if (NL80211_IFTYPE_AP == type)
2113 {
2114 /* As Loading WLAN Driver one interface being created for p2p device
2115 * address. This will take one HW STA and the max number of clients
2116 * that can connect to softAP will be reduced by one. so while changing
2117 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2118 * interface as it is not required in SoftAP mode.
2119 */
2120
2121 // Get P2P Adapter
2122 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2123
2124 if (pP2pAdapter)
2125 {
2126 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2127 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2128 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2129 }
2130 }
2131
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 //De-init the adapter.
2133 hdd_stop_adapter( pHddCtx, pAdapter );
2134 hdd_deinit_adapter( pHddCtx, pAdapter );
2135 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2136#ifdef WLAN_SOFTAP_FEATURE
2137#ifdef WLAN_FEATURE_P2P
2138 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2139 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2140#else
2141 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2142#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002143
2144 //Disable BMPS and IMPS if enabled
2145 //before starting Go
2146 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2147 {
2148 if(VOS_STATUS_E_FAILURE ==
2149 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2150 {
2151 //Fail to Exit BMPS
2152 VOS_ASSERT(0);
2153 }
2154 }
2155
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002156 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2157 (pConfig->apRandomBssidEnabled))
2158 {
2159 /* To meet Android requirements create a randomized
2160 MAC address of the form 02:1A:11:Fx:xx:xx */
2161 get_random_bytes(&ndev->dev_addr[3], 3);
2162 ndev->dev_addr[0] = 0x02;
2163 ndev->dev_addr[1] = 0x1A;
2164 ndev->dev_addr[2] = 0x11;
2165 ndev->dev_addr[3] |= 0xF0;
2166 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2167 VOS_MAC_ADDR_SIZE);
2168 pr_info("wlan: Generated HotSpot BSSID "
2169 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2170 ndev->dev_addr[0],
2171 ndev->dev_addr[1],
2172 ndev->dev_addr[2],
2173 ndev->dev_addr[3],
2174 ndev->dev_addr[4],
2175 ndev->dev_addr[5]);
2176 }
2177
Jeff Johnson295189b2012-06-20 16:38:30 -07002178 hdd_set_ap_ops( pAdapter->dev );
2179
2180 status = hdd_init_ap_mode(pAdapter);
2181 if(status != VOS_STATUS_SUCCESS)
2182 {
2183 hddLog(VOS_TRACE_LEVEL_FATAL,
2184 "%s: Error initializing the ap mode", __func__);
2185 return -EINVAL;
2186 }
2187 hdd_set_conparam(1);
2188
2189#endif
2190 /*interface type changed update in wiphy structure*/
2191 if(wdev)
2192 {
2193 wdev->iftype = type;
2194 pHddCtx->change_iface = type;
2195 }
2196 else
2197 {
2198 hddLog(VOS_TRACE_LEVEL_ERROR,
2199 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2200 return -EINVAL;
2201 }
2202 goto done;
2203 }
2204
2205 default:
2206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2207 __func__);
2208 return -EOPNOTSUPP;
2209 }
2210 }
2211 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2212#ifdef WLAN_FEATURE_P2P
2213 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2214#endif
2215 )
2216 {
2217 switch(type)
2218 {
2219 case NL80211_IFTYPE_STATION:
2220#ifdef WLAN_FEATURE_P2P
2221 case NL80211_IFTYPE_P2P_CLIENT:
2222#endif
2223 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002224 hdd_stop_adapter( pHddCtx, pAdapter );
2225 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002226 wdev->iftype = type;
2227#ifdef WLAN_FEATURE_P2P
2228 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2229 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
2230#endif
2231 hdd_set_conparam(0);
2232 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2234 hdd_set_station_ops( pAdapter->dev );
2235 status = hdd_init_station_mode( pAdapter );
2236 if( VOS_STATUS_SUCCESS != status )
2237 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002238 /* In case of JB, for P2P-GO, only change interface will be called,
2239 * This is the right place to enable back bmps_imps()
2240 */
2241 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002242 goto done;
2243 case NL80211_IFTYPE_AP:
2244#ifdef WLAN_FEATURE_P2P
2245 case NL80211_IFTYPE_P2P_GO:
2246#endif
2247 wdev->iftype = type;
2248#ifdef WLAN_FEATURE_P2P
2249 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2250 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2251#endif
2252 goto done;
2253 default:
2254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2255 __func__);
2256 return -EOPNOTSUPP;
2257
2258 }
2259
2260 }
2261 else
2262 {
2263 return -EOPNOTSUPP;
2264 }
2265
2266
2267 if(pRoamProfile)
2268 {
2269 if ( LastBSSType != pRoamProfile->BSSType )
2270 {
2271 /*interface type changed update in wiphy structure*/
2272 wdev->iftype = type;
2273
2274 /*the BSS mode changed, We need to issue disconnect
2275 if connected or in IBSS disconnect state*/
2276 if ( hdd_connGetConnectedBssType(
2277 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2278 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2279 {
2280 /*need to issue a disconnect to CSR.*/
2281 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2282 if( eHAL_STATUS_SUCCESS ==
2283 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2284 pAdapter->sessionId,
2285 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2286 {
2287 wait_for_completion_interruptible_timeout(
2288 &pAdapter->disconnect_comp_var,
2289 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2290 }
2291 }
2292 }
2293 }
2294
2295done:
2296 /*set bitmask based on updated value*/
2297 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2298#ifdef WLAN_BTAMP_FEATURE
2299 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2300 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2301 {
2302 //we are ok to do AMP
2303 pHddCtx->isAmpAllowed = VOS_TRUE;
2304 }
2305#endif //WLAN_BTAMP_FEATURE
2306 EXIT();
2307 return 0;
2308}
2309
2310static int wlan_hdd_change_station(struct wiphy *wiphy,
2311 struct net_device *dev,
2312 u8 *mac,
2313 struct station_parameters *params)
2314{
2315 VOS_STATUS status = VOS_STATUS_SUCCESS;
2316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2317 v_MACADDR_t STAMacAddress;
2318
Jeff Johnsone7245742012-09-05 17:12:55 -07002319 ENTER();
2320
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002321 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2322 {
2323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2324 "%s:LOGP in Progress. Ignore!!!", __func__);
2325 return -EAGAIN;
2326 }
2327
Jeff Johnson295189b2012-06-20 16:38:30 -07002328 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2329
2330 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2331#ifdef WLAN_FEATURE_P2P
2332 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2333#endif
2334 )
2335 {
2336 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2337 {
2338 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2339 WLANTL_STA_AUTHENTICATED);
2340
2341 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002342 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 return -EINVAL;
2344 }
2345 }
2346
Jeff Johnsone7245742012-09-05 17:12:55 -07002347 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002348 return status;
2349}
2350
2351/*
2352 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2353 * This function is used to get peer station index in IBSS mode
2354 */
2355static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2356{
2357 u8 idx = 0;
2358 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2359 ENTER();
2360 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2361 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2362 {
2363 if ( (0 !=
2364 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2365 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2366 temp, VOS_MAC_ADDR_SIZE)
2367 )
2368 {
2369 return idx;
2370 }
2371 }
2372 return idx;
2373}
2374
2375
2376/*
2377 * FUNCTION: wlan_hdd_cfg80211_add_key
2378 * This function is used to initialize the key information
2379 */
2380#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2381static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2382 struct net_device *ndev,
2383 u8 key_index, bool pairwise,
2384 const u8 *mac_addr,
2385 struct key_params *params
2386 )
2387#else
2388static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2389 struct net_device *ndev,
2390 u8 key_index, const u8 *mac_addr,
2391 struct key_params *params
2392 )
2393#endif
2394{
2395 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2396 tCsrRoamSetKey setKey;
2397 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2398 int status = 0;
2399 v_U32_t roamId= 0xFF;
2400 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2401 hdd_hostapd_state_t *pHostapdState;
2402 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002403 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002404
2405 ENTER();
2406
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002407 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2408 {
2409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s:LOGP in Progress. Ignore!!!", __func__);
2411 return -EAGAIN;
2412 }
2413
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2415 __func__,pAdapter->device_mode);
2416
2417 if (CSR_MAX_NUM_KEY <= key_index)
2418 {
2419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2420 key_index);
2421
2422 return -EINVAL;
2423 }
2424
2425 hddLog(VOS_TRACE_LEVEL_INFO,
2426 "%s: called with key index = %d & key length %d",
2427 __func__, key_index, params->key_len);
2428
2429 /*extract key idx, key len and key*/
2430 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2431 setKey.keyId = key_index;
2432 setKey.keyLength = params->key_len;
2433 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2434
2435 switch (params->cipher)
2436 {
2437 case WLAN_CIPHER_SUITE_WEP40:
2438 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2439 break;
2440
2441 case WLAN_CIPHER_SUITE_WEP104:
2442 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2443 break;
2444
2445 case WLAN_CIPHER_SUITE_TKIP:
2446 {
2447 u8 *pKey = &setKey.Key[0];
2448 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2449
2450 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2451
2452 /*Supplicant sends the 32bytes key in this order
2453
2454 |--------------|----------|----------|
2455 | Tk1 |TX-MIC | RX Mic |
2456 |--------------|----------|----------|
2457 <---16bytes---><--8bytes--><--8bytes-->
2458
2459 */
2460 /*Sme expects the 32 bytes key to be in the below order
2461
2462 |--------------|----------|----------|
2463 | Tk1 |RX-MIC | TX Mic |
2464 |--------------|----------|----------|
2465 <---16bytes---><--8bytes--><--8bytes-->
2466 */
2467 /* Copy the Temporal Key 1 (TK1) */
2468 vos_mem_copy(pKey, params->key,16);
2469
2470 /*Copy the rx mic first*/
2471 vos_mem_copy(&pKey[16],&params->key[24],8);
2472
2473 /*Copy the tx mic */
2474 vos_mem_copy(&pKey[24],&params->key[16],8);
2475
2476
2477 break;
2478 }
2479
2480 case WLAN_CIPHER_SUITE_CCMP:
2481 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2482 break;
2483
2484#ifdef FEATURE_WLAN_WAPI
2485 case WLAN_CIPHER_SUITE_SMS4:
2486 {
2487 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2488 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2489 params->key, params->key_len);
2490 return 0;
2491 }
2492#endif
2493#ifdef FEATURE_WLAN_CCX
2494 case WLAN_CIPHER_SUITE_KRK:
2495 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2496 break;
2497#endif
2498 default:
2499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2500 __func__, params->cipher);
2501 return -EOPNOTSUPP;
2502 }
2503
2504 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2505 __func__, setKey.encType);
2506
2507
2508
2509 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2510#ifdef WLAN_FEATURE_P2P
2511 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2512#endif
2513 )
2514 {
2515
2516
2517 if (
2518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2519 (!pairwise)
2520#else
2521 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2522#endif
2523 )
2524 {
2525 /* set group key*/
2526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2527 "%s- %d: setting Broacast key",
2528 __func__, __LINE__);
2529 setKey.keyDirection = eSIR_RX_ONLY;
2530 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2531 }
2532 else
2533 {
2534 /* set pairwise key*/
2535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2536 "%s- %d: setting pairwise key",
2537 __func__, __LINE__);
2538 setKey.keyDirection = eSIR_TX_RX;
2539 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2540 }
2541
2542 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2543 if( pHostapdState->bssState == BSS_START )
2544 {
2545 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2546
2547 if ( status != eHAL_STATUS_SUCCESS )
2548 {
2549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2550 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2551 __LINE__, status );
2552 }
2553 }
2554
2555 /* Saving WEP keys */
2556 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2557 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2558 {
2559 //Save the wep key in ap context. Issue setkey after the BSS is started.
2560 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2561 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2562 }
2563 else
2564 {
2565 //Save the key in ap context. Issue setkey after the BSS is started.
2566 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2567 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2568 }
2569 }
2570 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2571#ifdef WLAN_FEATURE_P2P
2572 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2573#endif
2574 )
2575 {
2576 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2577 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2578
2579 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
2580
2581 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
2582 params->key, params->key_len);
2583
2584 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2585
2586 if (!( ( IW_AUTH_KEY_MGMT_802_1X
2587 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2588 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2589 )
2590 &&
2591 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2592 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2593 )
2594 )
2595 {
2596 /* in case of static WEP, macaddr/bssid is not coming from nl80211
2597 * interface, copy bssid for pairwise key and group macaddr for
2598 * group key initialization*/
2599
2600 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2601
2602 pWextState->roamProfile.negotiatedUCEncryptionType =
2603 pHddStaCtx->conn_info.ucEncryptionType =
2604 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
2605 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
2606 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
2607
2608
2609 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2610 "%s: Negotiated encryption type %d", __func__,
2611 pWextState->roamProfile.negotiatedUCEncryptionType);
2612
2613 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
2614 &pWextState->roamProfile, true);
2615 setKey.keyLength = 0;
2616 setKey.keyDirection = eSIR_TX_RX;
2617
2618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2619 if (pairwise)
2620 {
2621#endif
2622 if (mac_addr)
2623 {
2624 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2625 }
2626 else
2627 {
2628 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
2629 * and peerMacAddress in case of IBSS*/
2630 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
2631 {
2632 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
2633 if (HDD_MAX_NUM_IBSS_STA != staidx)
2634 {
2635 vos_mem_copy(setKey.peerMac,
2636 &pHddStaCtx->conn_info.peerMacAddress[staidx],
2637 WNI_CFG_BSSID_LEN);
2638
2639 }
2640 else
2641 {
2642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
2643 __func__);
2644 return -EOPNOTSUPP;
2645 }
2646 }
2647 else
2648 {
2649 vos_mem_copy(setKey.peerMac,
2650 &pHddStaCtx->conn_info.bssId[0],
2651 WNI_CFG_BSSID_LEN);
2652 }
2653 }
2654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2655 }
2656 else
2657 {
2658 /* set group key*/
2659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2660 "%s- %d: setting Group key",
2661 __func__, __LINE__);
2662 setKey.keyDirection = eSIR_RX_ONLY;
2663 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2664 }
2665#endif
2666 }
2667 else if (
2668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2669 (!pairwise)
2670#else
2671 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2672#endif
2673 )
2674 {
2675 /* set group key*/
2676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2677 "%s- %d: setting Group key",
2678 __func__, __LINE__);
2679 setKey.keyDirection = eSIR_RX_ONLY;
2680 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2681 }
2682 else
2683 {
2684 /* set pairwise key*/
2685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2686 "%s- %d: setting pairwise key",
2687 __func__, __LINE__);
2688 setKey.keyDirection = eSIR_TX_RX;
2689 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2690 }
2691
2692 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2693 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2694 __func__, setKey.peerMac[0], setKey.peerMac[1],
2695 setKey.peerMac[2], setKey.peerMac[3],
2696 setKey.peerMac[4], setKey.peerMac[5],
2697 setKey.keyDirection);
2698
2699 vos_status = wlan_hdd_check_ula_done(pAdapter);
2700
2701 if ( vos_status != VOS_STATUS_SUCCESS )
2702 {
2703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2704 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
2705 __LINE__, vos_status );
2706
2707 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2708
2709 return -EINVAL;
2710
2711 }
2712
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002713#ifdef WLAN_FEATURE_VOWIFI_11R
2714 /* The supplicant may attempt to set the PTK once pre-authentication is done.
2715 Save the key in the UMAC and include it in the ADD BSS request */
2716 /*TODO 11r - is this used?? */
2717 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
2718 if( halStatus == eHAL_STATUS_SUCCESS )
2719 {
2720 return halStatus;
2721 }
2722#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07002723
2724 /* issue set key request to SME*/
2725 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2726 pAdapter->sessionId, &setKey, &roamId );
2727
2728 if ( 0 != status )
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
2732 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2733 return -EINVAL;
2734 }
2735
2736
2737 /* in case of IBSS as there was no information available about WEP keys during
2738 * IBSS join, group key intialized with NULL key, so re-initialize group key
2739 * with correct value*/
2740 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
2741 !( ( IW_AUTH_KEY_MGMT_802_1X
2742 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2743 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2744 )
2745 &&
2746 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2747 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2748 )
2749 )
2750 {
2751 setKey.keyDirection = eSIR_RX_ONLY;
2752 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2753
2754 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2755 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2756 __func__, setKey.peerMac[0], setKey.peerMac[1],
2757 setKey.peerMac[2], setKey.peerMac[3],
2758 setKey.peerMac[4], setKey.peerMac[5],
2759 setKey.keyDirection);
2760
2761 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2762 pAdapter->sessionId, &setKey, &roamId );
2763
2764 if ( 0 != status )
2765 {
2766 hddLog(VOS_TRACE_LEVEL_ERROR,
2767 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
2768 __func__, status);
2769 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2770 return -EINVAL;
2771 }
2772 }
2773 }
2774
2775 return 0;
2776}
2777
2778/*
2779 * FUNCTION: wlan_hdd_cfg80211_get_key
2780 * This function is used to get the key information
2781 */
2782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2783static int wlan_hdd_cfg80211_get_key(
2784 struct wiphy *wiphy,
2785 struct net_device *ndev,
2786 u8 key_index, bool pairwise,
2787 const u8 *mac_addr, void *cookie,
2788 void (*callback)(void *cookie, struct key_params*)
2789 )
2790#else
2791static int wlan_hdd_cfg80211_get_key(
2792 struct wiphy *wiphy,
2793 struct net_device *ndev,
2794 u8 key_index, const u8 *mac_addr, void *cookie,
2795 void (*callback)(void *cookie, struct key_params*)
2796 )
2797#endif
2798{
2799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2800 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2801 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2802 struct key_params params;
2803
2804 ENTER();
2805
2806 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2807 __func__,pAdapter->device_mode);
2808
2809 memset(&params, 0, sizeof(params));
2810
2811 if (CSR_MAX_NUM_KEY <= key_index)
2812 {
2813 return -EINVAL;
2814 }
2815
2816 switch(pRoamProfile->EncryptionType.encryptionType[0])
2817 {
2818 case eCSR_ENCRYPT_TYPE_NONE:
2819 params.cipher = IW_AUTH_CIPHER_NONE;
2820 break;
2821
2822 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2823 case eCSR_ENCRYPT_TYPE_WEP40:
2824 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2825 break;
2826
2827 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2828 case eCSR_ENCRYPT_TYPE_WEP104:
2829 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2830 break;
2831
2832 case eCSR_ENCRYPT_TYPE_TKIP:
2833 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2834 break;
2835
2836 case eCSR_ENCRYPT_TYPE_AES:
2837 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2838 break;
2839
2840 default:
2841 params.cipher = IW_AUTH_CIPHER_NONE;
2842 break;
2843 }
2844
2845 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
2846 params.seq_len = 0;
2847 params.seq = NULL;
2848 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
2849 callback(cookie, &params);
2850 return 0;
2851}
2852
2853/*
2854 * FUNCTION: wlan_hdd_cfg80211_del_key
2855 * This function is used to delete the key information
2856 */
2857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2858static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
2859 struct net_device *ndev,
2860 u8 key_index,
2861 bool pairwise,
2862 const u8 *mac_addr
2863 )
2864#else
2865static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
2866 struct net_device *ndev,
2867 u8 key_index,
2868 const u8 *mac_addr
2869 )
2870#endif
2871{
2872 int status = 0;
2873
2874 //This code needs to be revisited. There is sme_removeKey API, we should
2875 //plan to use that. After the change to use correct index in setkey,
2876 //it is observed that this is invalidating peer
2877 //key index whenever re-key is done. This is affecting data link.
2878 //It should be ok to ignore del_key.
2879#if 0
2880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2881 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2882 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2883 tCsrRoamSetKey setKey;
2884 v_U32_t roamId= 0xFF;
2885
2886 ENTER();
2887
2888 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
2889 __func__,pAdapter->device_mode);
2890
2891 if (CSR_MAX_NUM_KEY <= key_index)
2892 {
2893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2894 key_index);
2895
2896 return -EINVAL;
2897 }
2898
2899 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2900 setKey.keyId = key_index;
2901
2902 if (mac_addr)
2903 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2904 else
2905 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2906
2907 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2908
2909 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2910#ifdef WLAN_FEATURE_P2P
2911 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2912#endif
2913 )
2914 {
2915
2916 hdd_hostapd_state_t *pHostapdState =
2917 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2918 if( pHostapdState->bssState == BSS_START)
2919 {
2920 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2921
2922 if ( status != eHAL_STATUS_SUCCESS )
2923 {
2924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2925 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2926 __LINE__, status );
2927 }
2928 }
2929 }
2930 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2931#ifdef WLAN_FEATURE_P2P
2932 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2933#endif
2934 )
2935 {
2936 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2937
2938 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2939
2940 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2941 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
2942 __func__, setKey.peerMac[0], setKey.peerMac[1],
2943 setKey.peerMac[2], setKey.peerMac[3],
2944 setKey.peerMac[4], setKey.peerMac[5]);
2945 if(pAdapter->sessionCtx.station.conn_info.connState ==
2946 eConnectionState_Associated)
2947 {
2948 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2949 pAdapter->sessionId, &setKey, &roamId );
2950
2951 if ( 0 != status )
2952 {
2953 hddLog(VOS_TRACE_LEVEL_ERROR,
2954 "%s: sme_RoamSetKey failure, returned %d",
2955 __func__, status);
2956 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2957 return -EINVAL;
2958 }
2959 }
2960 }
2961#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002962 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002963 return status;
2964}
2965
2966/*
2967 * FUNCTION: wlan_hdd_cfg80211_set_default_key
2968 * This function is used to set the default tx key index
2969 */
2970#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2971static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
2972 struct net_device *ndev,
2973 u8 key_index,
2974 bool unicast, bool multicast)
2975#else
2976static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
2977 struct net_device *ndev,
2978 u8 key_index)
2979#endif
2980{
2981 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2982 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2983 int status = 0;
2984 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2985
2986 ENTER();
2987
2988 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
2989 __func__,pAdapter->device_mode, key_index);
2990
2991 if (CSR_MAX_NUM_KEY <= key_index)
2992 {
2993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2994 key_index);
2995
2996 return -EINVAL;
2997 }
2998
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002999 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3000 {
3001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3002 "%s:LOGP in Progress. Ignore!!!", __func__);
3003 return -EAGAIN;
3004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003005
3006 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3007#ifdef WLAN_FEATURE_P2P
3008 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3009#endif
3010 )
3011 {
3012 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3013 (eCSR_ENCRYPT_TYPE_TKIP !=
3014 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3015 (eCSR_ENCRYPT_TYPE_AES !=
3016 pWextState->roamProfile.EncryptionType.encryptionType[0])
3017 )
3018 {
3019 /* if default key index is not same as previous one,
3020 * then update the default key index */
3021
3022 tCsrRoamSetKey setKey;
3023 v_U32_t roamId= 0xFF;
3024 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3025
3026 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3027 __func__, key_index);
3028
3029 Keys->defaultIndex = (u8)key_index;
3030 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3031 setKey.keyId = key_index;
3032 setKey.keyLength = Keys->KeyLength[key_index];
3033
3034 vos_mem_copy(&setKey.Key[0],
3035 &Keys->KeyMaterial[key_index][0],
3036 Keys->KeyLength[key_index]);
3037
3038 setKey.keyDirection = eSIR_TX_ONLY;
3039
3040 vos_mem_copy(setKey.peerMac,
3041 &pHddStaCtx->conn_info.bssId[0],
3042 WNI_CFG_BSSID_LEN);
3043
3044 setKey.encType =
3045 pWextState->roamProfile.EncryptionType.encryptionType[0];
3046
3047 /* issue set key request */
3048 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3049 pAdapter->sessionId, &setKey, &roamId );
3050
3051 if ( 0 != status )
3052 {
3053 hddLog(VOS_TRACE_LEVEL_ERROR,
3054 "%s: sme_RoamSetKey failed, returned %d", __func__,
3055 status);
3056 return -EINVAL;
3057 }
3058 }
3059 }
3060
3061 /* In SoftAp mode setting key direction for default mode */
3062 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3063 {
3064 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3065 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3066 (eCSR_ENCRYPT_TYPE_AES !=
3067 pWextState->roamProfile.EncryptionType.encryptionType[0])
3068 )
3069 {
3070 /* Saving key direction for default key index to TX default */
3071 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3072 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3073 }
3074 }
3075
3076 return status;
3077}
3078
3079/**
3080 * FUNCTION: wlan_hdd_cfg80211_set_channel
3081 * This function is used to set the channel number
3082 */
3083int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
3084 struct ieee80211_channel *chan,
3085 enum nl80211_channel_type channel_type
3086 )
3087{
3088 v_U32_t num_ch = 0;
3089 u32 channel = 0;
3090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3091 int freq = chan->center_freq; /* freq is in MHZ */
3092
3093 ENTER();
3094
3095 hddLog(VOS_TRACE_LEVEL_INFO,
3096 "%s: device_mode = %d freq = %d \n",__func__,
3097 pAdapter->device_mode, chan->center_freq);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07003098 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3099 {
3100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3101 return -EAGAIN;
3102 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003103
3104 /*
3105 * Do freq to chan conversion
3106 * TODO: for 11a
3107 */
3108
3109 channel = ieee80211_frequency_to_channel(freq);
3110
3111 /* Check freq range */
3112 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3113 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
3114 {
3115 hddLog(VOS_TRACE_LEVEL_ERROR,
3116 "%s: Channel [%d] is outside valid range from %d to %d\n",
3117 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3118 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3119 return -EINVAL;
3120 }
3121
3122 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3123
3124 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
3125#ifdef WLAN_FEATURE_P2P
3126 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
3127#endif
3128 )
3129 {
3130 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
3131 {
3132 hddLog(VOS_TRACE_LEVEL_ERROR,
3133 "%s: Invalid Channel [%d] \n", __func__, channel);
3134 return -EINVAL;
3135 }
3136 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3137 "%s: set channel to [%d] for device mode =%d",
3138 __func__, channel,pAdapter->device_mode);
3139 }
3140 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3141#ifdef WLAN_FEATURE_P2P
3142 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3143#endif
3144 )
3145 {
3146 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3147 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
3148 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3149
3150 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
3151 {
3152 /* Link is up then return cant set channel*/
3153 hddLog( VOS_TRACE_LEVEL_ERROR,
3154 "%s: IBSS Associated, can't set the channel\n", __func__);
3155 return -EINVAL;
3156 }
3157
3158 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
3159 pHddStaCtx->conn_info.operationChannel = channel;
3160 pRoamProfile->ChannelInfo.ChannelList =
3161 &pHddStaCtx->conn_info.operationChannel;
3162 }
3163 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3164#ifdef WLAN_FEATURE_P2P
3165 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3166#endif
3167 )
3168 {
3169 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
3170
3171 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3172 {
3173 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3174
3175 /* If auto channel selection is configured as enable/ 1 then ignore
3176 channel set by supplicant
3177 */
3178 if ( cfg_param->apAutoChannelSelection )
3179 {
3180 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
3181
3182 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3183 "%s: set channel to auto channel (0) for device mode =%d",
3184 __func__, pAdapter->device_mode);
3185 }
3186 }
3187 }
3188 else
3189 {
3190 hddLog(VOS_TRACE_LEVEL_FATAL,
3191 "%s: Invalid device mode failed to set valid channel", __func__);
3192 return -EINVAL;
3193 }
3194 EXIT();
3195 return 0;
3196}
3197
3198
3199
3200/*
3201 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3202 * This function is used to inform the BSS details to nl80211 interface.
3203 */
3204static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3205 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3206{
3207 struct net_device *dev = pAdapter->dev;
3208 struct wireless_dev *wdev = dev->ieee80211_ptr;
3209 struct wiphy *wiphy = wdev->wiphy;
3210 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3211 int chan_no;
3212 int ie_length;
3213 const char *ie;
3214 unsigned int freq;
3215 struct ieee80211_channel *chan;
3216 int rssi = 0;
3217 struct cfg80211_bss *bss = NULL;
3218
3219 ENTER();
3220
3221 if( NULL == pBssDesc )
3222 {
3223 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3224 return bss;
3225 }
3226
3227 chan_no = pBssDesc->channelId;
3228 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3229 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3230
3231 if( NULL == ie )
3232 {
3233 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3234 return bss;
3235 }
3236
3237#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3238 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3239 {
3240 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3241 }
3242 else
3243 {
3244 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3245 }
3246#else
3247 freq = ieee80211_channel_to_frequency(chan_no);
3248#endif
3249
3250 chan = __ieee80211_get_channel(wiphy, freq);
3251
3252 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3253 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3254 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3255 if (bss == NULL)
3256 {
3257 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3258
3259 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3260 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3261 pBssDesc->capabilityInfo,
3262 pBssDesc->beaconInterval, ie, ie_length,
3263 rssi, GFP_KERNEL ));
3264}
3265 else
3266 {
3267 return bss;
3268 }
3269}
3270
3271
3272
3273/*
3274 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3275 * This function is used to inform the BSS details to nl80211 interface.
3276 */
3277struct cfg80211_bss*
3278wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3279 tSirBssDescription *bss_desc
3280 )
3281{
3282 /*
3283 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3284 already exists in bss data base of cfg80211 for that particular BSS ID.
3285 Using cfg80211_inform_bss_frame to update the bss entry instead of
3286 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3287 now there is no possibility to get the mgmt(probe response) frame from PE,
3288 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3289 cfg80211_inform_bss_frame.
3290 */
3291 struct net_device *dev = pAdapter->dev;
3292 struct wireless_dev *wdev = dev->ieee80211_ptr;
3293 struct wiphy *wiphy = wdev->wiphy;
3294 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003295#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3296 qcom_ie_age *qie_age = NULL;
3297 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3298#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003299 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003300#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 const char *ie =
3302 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3303 unsigned int freq;
3304 struct ieee80211_channel *chan;
3305 struct ieee80211_mgmt *mgmt =
3306 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3307 struct cfg80211_bss *bss_status = NULL;
3308 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3309 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003310#ifdef WLAN_OPEN_SOURCE
3311 struct timespec ts;
3312#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003313
3314 ENTER();
3315
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003316 if (!mgmt)
3317 return NULL;
3318
Jeff Johnson295189b2012-06-20 16:38:30 -07003319 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003320
3321#ifdef WLAN_OPEN_SOURCE
3322 /* Android does not want the timestamp from the frame.
3323 Instead it wants a monotonic increasing value */
3324 get_monotonic_boottime(&ts);
3325 mgmt->u.probe_resp.timestamp =
3326 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3327#else
3328 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003329 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3330 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003331
3332#endif
3333
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3335 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003336
3337#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3338 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3339 /* Assuming this is the last IE, copy at the end */
3340 ie_length -=sizeof(qcom_ie_age);
3341 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3342 qie_age->element_id = QCOM_VENDOR_IE_ID;
3343 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3344 qie_age->oui_1 = QCOM_OUI1;
3345 qie_age->oui_2 = QCOM_OUI2;
3346 qie_age->oui_3 = QCOM_OUI3;
3347 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3348 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3349#endif
3350
Jeff Johnson295189b2012-06-20 16:38:30 -07003351 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3352
3353 mgmt->frame_control |=
3354 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3355
3356#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3357 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3358 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3359 {
3360 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3361 }
3362 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3363 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3364
3365 {
3366 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3367 }
3368 else
3369 {
3370 kfree(mgmt);
3371 return NULL;
3372 }
3373#else
3374 freq = ieee80211_channel_to_frequency(chan_no);
3375#endif
3376 chan = __ieee80211_get_channel(wiphy, freq);
3377
3378 /*To keep the rssi icon of the connected AP in the scan window
3379 *and the rssi icon of the wireless networks in sync
3380 * */
3381 if (( eConnectionState_Associated ==
3382 pAdapter->sessionCtx.station.conn_info.connState ) &&
3383 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3384 pAdapter->sessionCtx.station.conn_info.bssId,
3385 WNI_CFG_BSSID_LEN)))
3386 {
3387 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3388 rssi = (pAdapter->rssi * 100);
3389 }
3390 else
3391 {
3392 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3393 }
3394
3395 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3396 frame_len, rssi, GFP_KERNEL);
3397 kfree(mgmt);
3398 return bss_status;
3399}
3400
3401/*
3402 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3403 * This function is used to update the BSS data base of CFG8011
3404 */
3405struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3406 tCsrRoamInfo *pRoamInfo
3407 )
3408{
3409 tCsrRoamConnectedProfile roamProfile;
3410 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3411 struct cfg80211_bss *bss = NULL;
3412
3413 ENTER();
3414
3415 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3416 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3417
3418 if (NULL != roamProfile.pBssDesc)
3419 {
3420 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3421 &roamProfile);
3422
3423 if (NULL == bss)
3424 {
3425 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3426 __func__);
3427 }
3428
3429 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3430 }
3431 else
3432 {
3433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3434 __func__);
3435 }
3436 return bss;
3437}
3438
3439/*
3440 * FUNCTION: wlan_hdd_cfg80211_update_bss
3441 */
3442static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3443 hdd_adapter_t *pAdapter
3444 )
3445{
3446 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3447 tCsrScanResultInfo *pScanResult;
3448 eHalStatus status = 0;
3449 tScanResultHandle pResult;
3450 struct cfg80211_bss *bss_status = NULL;
3451
3452 ENTER();
3453
3454 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3455 {
3456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3457 return -EAGAIN;
3458 }
3459
3460 /*
3461 * start getting scan results and populate cgf80211 BSS database
3462 */
3463 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3464
3465 /* no scan results */
3466 if (NULL == pResult)
3467 {
3468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3469 return status;
3470 }
3471
3472 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3473
3474 while (pScanResult)
3475 {
3476 /*
3477 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3478 * entry already exists in bss data base of cfg80211 for that
3479 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3480 * bss entry instead of cfg80211_inform_bss, But this call expects
3481 * mgmt packet as input. As of now there is no possibility to get
3482 * the mgmt(probe response) frame from PE, converting bss_desc to
3483 * ieee80211_mgmt(probe response) and passing to c
3484 * fg80211_inform_bss_frame.
3485 * */
3486
3487 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3488 &pScanResult->BssDescriptor);
3489
3490
3491 if (NULL == bss_status)
3492 {
3493 hddLog(VOS_TRACE_LEVEL_INFO,
3494 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3495 }
3496 else
3497 {
3498 cfg80211_put_bss(bss_status);
3499 }
3500
3501 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3502 }
3503
3504 sme_ScanResultPurge(hHal, pResult);
3505
3506 return 0;
3507}
3508
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003509void
3510hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3511{
3512 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003513 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3514 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3515 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003516} /****** end hddPrintMacAddr() ******/
3517
3518void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003519hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003520{
3521 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003522 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3523 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3524 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3525 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003526} /****** end hddPrintPmkId() ******/
3527
3528//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3529//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3530
3531//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3532//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3533
3534#define dump_bssid(bssid) \
3535 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003536 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3537 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3538 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003539 }
3540
3541#define dump_pmkid(pMac, pmkid) \
3542 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003543 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3544 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3545 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003546 }
3547
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003548#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003549/*
3550 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3551 * This function is used to notify the supplicant of a new PMKSA candidate.
3552 */
3553int wlan_hdd_cfg80211_pmksa_candidate_notify(
3554 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3555 int index, bool preauth )
3556{
Jeff Johnsone7245742012-09-05 17:12:55 -07003557#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003558 struct net_device *dev = pAdapter->dev;
3559
3560 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003561 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003562
3563 if( NULL == pRoamInfo )
3564 {
3565 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3566 return -EINVAL;
3567 }
3568
3569 dump_bssid(pRoamInfo->bssid);
3570 cfg80211_pmksa_candidate_notify(dev, index,
3571 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003572#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003573 return 0;
3574}
3575#endif //FEATURE_WLAN_LFR
3576
Jeff Johnson295189b2012-06-20 16:38:30 -07003577/*
3578 * FUNCTION: hdd_cfg80211_scan_done_callback
3579 * scanning callback function, called after finishing scan
3580 *
3581 */
3582static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3583 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3584{
3585 struct net_device *dev = (struct net_device *) pContext;
3586 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3587 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003588 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3589 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003590 struct cfg80211_scan_request *req = NULL;
3591 int ret = 0;
3592
3593 ENTER();
3594
3595 hddLog(VOS_TRACE_LEVEL_INFO,
3596 "%s called with halHandle = %p, pContext = %p,"
3597 "scanID = %d, returned status = %d\n",
3598 __func__, halHandle, pContext, (int) scanId, (int) status);
3599
3600 //Block on scan req completion variable. Can't wait forever though.
3601 ret = wait_for_completion_interruptible_timeout(
3602 &pScanInfo->scan_req_completion_event,
3603 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3604 if (!ret)
3605 {
3606 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003607 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003608 }
3609
3610 if(pScanInfo->mScanPending != VOS_TRUE)
3611 {
3612 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003613 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003614 }
3615
3616 /* Check the scanId */
3617 if (pScanInfo->scanId != scanId)
3618 {
3619 hddLog(VOS_TRACE_LEVEL_INFO,
3620 "%s called with mismatched scanId pScanInfo->scanId = %d "
3621 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3622 (int) scanId);
3623 }
3624
Jeff Johnson295189b2012-06-20 16:38:30 -07003625 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3626 pAdapter);
3627
3628 if (0 > ret)
3629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3630
3631
3632 /* If any client wait scan result through WEXT
3633 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003634 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003635 {
3636 /* The other scan request waiting for current scan finish
3637 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003638 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003639 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003640 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 }
3642 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003643 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003644 {
3645 struct net_device *dev = pAdapter->dev;
3646 union iwreq_data wrqu;
3647 int we_event;
3648 char *msg;
3649
3650 memset(&wrqu, '\0', sizeof(wrqu));
3651 we_event = SIOCGIWSCAN;
3652 msg = NULL;
3653 wireless_send_event(dev, we_event, &wrqu, msg);
3654 }
3655 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003656 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003657
3658 /* Get the Scan Req */
3659 req = pAdapter->request;
3660
3661 if (!req)
3662 {
3663 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003664 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003665 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003666 }
3667
3668 /*
3669 * setting up 0, just in case.
3670 */
3671 req->n_ssids = 0;
3672 req->n_channels = 0;
3673 req->ie = 0;
3674
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07003676 /* Scan is no longer pending */
3677 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003678
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07003679 /*
3680 * cfg80211_scan_done informing NL80211 about completion
3681 * of scanning
3682 */
3683 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08003684 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07003685#ifdef WLAN_FEATURE_P2P
3686 /* Flush out scan result after p2p_serach is done */
Jeff Johnsone7245742012-09-05 17:12:55 -07003687 if(pScanInfo->flushP2pScanResults)
Jeff Johnson295189b2012-06-20 16:38:30 -07003688 {
3689 tANI_U8 sessionId = pAdapter->sessionId;
Madan Mohan Koyyalamudiab41d0f2012-10-31 17:17:10 -07003690 sme_ScanFlushP2PResult(WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId);
Jeff Johnsone7245742012-09-05 17:12:55 -07003691 pScanInfo->flushP2pScanResults = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 }
3693#endif
3694
Jeff Johnsone7245742012-09-05 17:12:55 -07003695allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003696 /* release the wake lock at the end of the scan*/
3697 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003698
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07003699 /* Acquire wakelock to handle the case where APP's tries to suspend
3700 * immediatly after the driver gets connect request(i.e after scan)
3701 * from supplicant, this result in app's is suspending and not able
3702 * to process the connect request to AP */
3703 hdd_allow_suspend_timeout(100);
3704
Jeff Johnson295189b2012-06-20 16:38:30 -07003705 EXIT();
3706 return 0;
3707}
3708
3709/*
3710 * FUNCTION: wlan_hdd_cfg80211_scan
3711 * this scan respond to scan trigger and update cfg80211 scan database
3712 * later, scan dump command can be used to recieve scan results
3713 */
3714int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, struct net_device *dev,
3715 struct cfg80211_scan_request *request)
3716{
3717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3718 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3719 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3720 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3721 tCsrScanRequest scanRequest;
3722 tANI_U8 *channelList = NULL, i;
3723 v_U32_t scanId = 0;
3724 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003725 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003726#ifdef WLAN_FEATURE_P2P
3727 v_U8_t* pP2pIe = NULL;
3728#endif
3729
3730 ENTER();
3731
3732 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3733 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003734
3735 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
3736 (eConnectionState_Connecting ==
3737 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
3738 {
3739 hddLog(VOS_TRACE_LEVEL_ERROR,
3740 "%s: Connection in progress: Scan request denied (EBUSY)", __func__);
3741 return -EBUSY;
3742 }
3743
Jeff Johnson295189b2012-06-20 16:38:30 -07003744#ifdef WLAN_BTAMP_FEATURE
3745 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003746 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07003747 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003748 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003749 "%s: No scanning when AMP is on", __func__);
3750 return -EOPNOTSUPP;
3751 }
3752#endif
3753 //Scan on any other interface is not supported.
3754 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
3755 {
3756 hddLog(VOS_TRACE_LEVEL_ERROR,
3757 "%s: Not scanning on device_mode = %d",
3758 __func__, pAdapter->device_mode);
3759 return -EOPNOTSUPP;
3760 }
3761
3762 if (TRUE == pScanInfo->mScanPending)
3763 {
3764 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
3765 return -EBUSY;
3766 }
3767
3768 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3769 {
3770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3771 "%s:LOGP in Progress. Ignore!!!", __func__);
3772 return -EAGAIN;
3773 }
3774
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07003775 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
3776 {
3777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3778 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
3779 return -EAGAIN;
3780 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07003781 //Don't Allow Scan and return busy if Remain On
3782 //Channel and action frame is pending
3783 //Otherwise Cancel Remain On Channel and allow Scan
3784 //If no action frame pending
3785 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
3786 {
3787 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
3788 return -EBUSY;
3789 }
3790
Jeff Johnson295189b2012-06-20 16:38:30 -07003791 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
3792 {
3793 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
3794 "%s: Aquire lock fail", __func__);
3795 return -EAGAIN;
3796 }
3797 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
3798 {
3799 hddLog(VOS_TRACE_LEVEL_WARN,
3800 "%s: MAX TM Level Scan not allowed", __func__);
3801 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3802 return -EBUSY;
3803 }
3804 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3805
3806 vos_mem_zero( &scanRequest, sizeof(scanRequest));
3807
3808 if (NULL != request)
3809 {
3810 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
3811 (int)request->n_ssids);
3812
3813 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
3814 * Becasue of this, driver is assuming that this is not wildcard scan and so
3815 * is not aging out the scan results.
3816 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07003817 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07003818 {
3819 request->n_ssids = 0;
3820 }
3821
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003822 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07003823 {
3824 tCsrSSIDInfo *SsidInfo;
3825 int j;
3826 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
3827 /* Allocate num_ssid tCsrSSIDInfo structure */
3828 SsidInfo = scanRequest.SSIDs.SSIDList =
3829 ( tCsrSSIDInfo *)vos_mem_malloc(
3830 request->n_ssids*sizeof(tCsrSSIDInfo));
3831
3832 if(NULL == scanRequest.SSIDs.SSIDList)
3833 {
3834 hddLog(VOS_TRACE_LEVEL_ERROR,
3835 "memory alloc failed SSIDInfo buffer");
3836 return -ENOMEM;
3837 }
3838
3839 /* copy all the ssid's and their length */
3840 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
3841 {
3842 /* get the ssid length */
3843 SsidInfo->SSID.length = request->ssids[j].ssid_len;
3844 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
3845 SsidInfo->SSID.length);
3846 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
3847 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
3848 j, SsidInfo->SSID.ssId);
3849 }
3850 /* set the scan type to active */
3851 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3852 }
3853 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
3854 {
3855 /* set the scan type to active */
3856 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3857 }
3858 else
3859 {
3860 /*Set the scan type to default type, in this case it is ACTIVE*/
3861 scanRequest.scanType = pScanInfo->scan_mode;
3862 }
3863 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
3864 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
3865 }
3866 else
3867 {
3868 /* set the scan type to active */
3869 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3870 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
3871
3872 /* set min and max channel time to zero */
3873 scanRequest.minChnTime = 0;
3874 scanRequest.maxChnTime = 0;
3875 }
3876
3877 /* set BSSType to default type */
3878 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
3879
3880 /*TODO: scan the requested channels only*/
3881
3882 /*Right now scanning all the channels */
3883 if( request )
3884 {
3885 if( request->n_channels )
3886 {
3887 channelList = vos_mem_malloc( request->n_channels );
3888 if( NULL == channelList )
3889 {
3890 status = -ENOMEM;
3891 goto free_mem;
3892 }
3893
3894 for( i = 0 ; i < request->n_channels ; i++ )
3895 channelList[i] = request->channels[i]->hw_value;
3896 }
3897
3898 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
3899 scanRequest.ChannelInfo.ChannelList = channelList;
3900
3901 /* set requestType to full scan */
3902 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
3903
3904 if( request->ie_len )
3905 {
3906 /* save this for future association (join requires this) */
3907 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
3908 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
3909 pScanInfo->scanAddIE.length = request->ie_len;
3910
3911 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07003912 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
3913 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 )
3915 {
3916 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
3917 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
3918 }
3919
3920 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
3921 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
3922
3923#ifdef WLAN_FEATURE_P2P
3924 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
3925 request->ie_len);
3926 if (pP2pIe != NULL)
3927 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07003928#ifdef WLAN_FEATURE_P2P_DEBUG
3929 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
3930 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
3931 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
3932 {
3933 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
3934 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
3935 "Go nego completed to Connection is started");
3936 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
3937 "for 8way Handshake");
3938 }
3939 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
3940 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
3941 {
3942 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
3943 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
3944 "Disconnected state to Connection is started");
3945 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
3946 "for 4way Handshake");
3947 }
3948#endif
3949
Jeff Johnsone7245742012-09-05 17:12:55 -07003950 /* no_cck will be set during p2p find to disable 11b rates */
3951 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07003952 {
3953 tANI_U8 sessionId = pAdapter->sessionId;
3954 hddLog(VOS_TRACE_LEVEL_INFO,
3955 "%s: This is a P2P Search", __func__);
3956 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07003957
3958 /* Flush the scan results only for P2P search.
3959 P2P search happens on 3 social channels (1, 6, 11) */
3960 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
3961 {
3962 pScanInfo->flushP2pScanResults = 1;
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07003963 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnsone7245742012-09-05 17:12:55 -07003964 sessionId );
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07003965 /* set requestType to P2P Discovery */
3966 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07003967 }
3968
3969 /*
3970 Skip Dfs Channel in case of P2P Search
3971 if it is set in ini file
3972 */
3973 if(cfg_param->skipDfsChnlInP2pSearch)
3974 {
3975 scanRequest.skipDfsChnlInP2pSearch = 1;
3976 }
3977 else
3978 {
3979 scanRequest.skipDfsChnlInP2pSearch = 0;
3980 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003981
Jeff Johnson295189b2012-06-20 16:38:30 -07003982 }
3983 }
3984#endif
3985 }
3986 }
3987
3988 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
3989
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003990 /* acquire the wakelock to avoid the apps suspend during the scan. To
3991 * address the following issues.
3992 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
3993 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
3994 * for long time, this result in apps running at full power for long time.
3995 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
3996 * be stuck in full power because of resume BMPS
3997 */
3998 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003999
4000 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004001 pAdapter->sessionId, &scanRequest, &scanId,
4002 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004003
Jeff Johnson295189b2012-06-20 16:38:30 -07004004 if (eHAL_STATUS_SUCCESS != status)
4005 {
4006 hddLog(VOS_TRACE_LEVEL_ERROR,
4007 "%s: sme_ScanRequest returned error %d", __func__, status);
4008 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004009 if(eHAL_STATUS_RESOURCES == status)
4010 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004011 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 -07004012 status = -EBUSY;
4013 } else {
4014 status = -EIO;
4015 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004016 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004017 goto free_mem;
4018 }
4019
4020 pScanInfo->mScanPending = TRUE;
4021 pAdapter->request = request;
4022 pScanInfo->scanId = scanId;
4023
4024 complete(&pScanInfo->scan_req_completion_event);
4025
4026free_mem:
4027 if( scanRequest.SSIDs.SSIDList )
4028 {
4029 vos_mem_free(scanRequest.SSIDs.SSIDList);
4030 }
4031
4032 if( channelList )
4033 vos_mem_free( channelList );
4034
4035 EXIT();
4036
4037 return status;
4038}
4039
4040/*
4041 * FUNCTION: wlan_hdd_cfg80211_connect_start
4042 * This function is used to start the association process
4043 */
4044int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004045 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004046{
4047 int status = 0;
4048 hdd_wext_state_t *pWextState;
4049 v_U32_t roamId;
4050 tCsrRoamProfile *pRoamProfile;
4051 eMib_dot11DesiredBssType connectedBssType;
4052 eCsrAuthType RSNAuthType;
4053
4054 ENTER();
4055
4056 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4057
4058 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4059 {
4060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4061 return -EINVAL;
4062 }
4063
4064 pRoamProfile = &pWextState->roamProfile;
4065
4066 if (pRoamProfile)
4067 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004068 int ret = 0;
4069 hdd_station_ctx_t *pHddStaCtx;
4070 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4071 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4072
4073 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4074 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4075 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 {
4077 /* Issue disconnect to CSR */
4078 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4079 if( eHAL_STATUS_SUCCESS ==
4080 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4081 pAdapter->sessionId,
4082 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4083 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004084 ret = wait_for_completion_interruptible_timeout(
4085 &pAdapter->disconnect_comp_var,
4086 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4087 if (0 == ret)
4088 {
4089 VOS_ASSERT(0);
4090 }
4091 }
4092 }
4093 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4094 {
4095 ret = wait_for_completion_interruptible_timeout(
4096 &pAdapter->disconnect_comp_var,
4097 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4098 if (0 == ret)
4099 {
4100 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004101 }
4102 }
4103
4104 if (HDD_WMM_USER_MODE_NO_QOS ==
4105 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4106 {
4107 /*QoS not enabled in cfg file*/
4108 pRoamProfile->uapsd_mask = 0;
4109 }
4110 else
4111 {
4112 /*QoS enabled, update uapsd mask from cfg file*/
4113 pRoamProfile->uapsd_mask =
4114 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4115 }
4116
4117 pRoamProfile->SSIDs.numOfSSIDs = 1;
4118 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4119 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4120 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4121 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4122 ssid, ssid_len);
4123
4124 if (bssid)
4125 {
4126 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4127 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4128 WNI_CFG_BSSID_LEN);
4129 /* Save BSSID in seperate variable as well, as RoamProfile
4130 BSSID is getting zeroed out in the association process. And in
4131 case of join failure we should send valid BSSID to supplicant
4132 */
4133 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4134 WNI_CFG_BSSID_LEN);
4135 }
4136
4137 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4138 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4139 {
4140 /*set gen ie*/
4141 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4142 /*set auth*/
4143 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4144 }
4145 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4146 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4147 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4148 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4149 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4150 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4151 )
4152 {
4153 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4154 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4155 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4156 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4157 eCSR_AUTH_TYPE_AUTOSWITCH;
4158 pWextState->roamProfile.AuthType.authType[0] =
4159 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4160 }
4161#ifdef FEATURE_WLAN_WAPI
4162 if (pAdapter->wapi_info.nWapiMode)
4163 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004164 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 switch (pAdapter->wapi_info.wapiAuthMode)
4166 {
4167 case WAPI_AUTH_MODE_PSK:
4168 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004169 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004170 pAdapter->wapi_info.wapiAuthMode);
4171 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4172 break;
4173 }
4174 case WAPI_AUTH_MODE_CERT:
4175 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004176 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 pAdapter->wapi_info.wapiAuthMode);
4178 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4179 break;
4180 }
4181 } // End of switch
4182 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4183 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4184 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004185 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004186 pRoamProfile->AuthType.numEntries = 1;
4187 pRoamProfile->EncryptionType.numEntries = 1;
4188 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4189 pRoamProfile->mcEncryptionType.numEntries = 1;
4190 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4191 }
4192 }
4193#endif /* FEATURE_WLAN_WAPI */
4194 pRoamProfile->csrPersona = pAdapter->device_mode;
4195
Jeff Johnson32d95a32012-09-10 13:15:23 -07004196 if( operatingChannel )
4197 {
4198 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4199 pRoamProfile->ChannelInfo.numOfChannels = 1;
4200 }
4201
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4203 pAdapter->sessionId, pRoamProfile, &roamId);
4204
Jeff Johnson32d95a32012-09-10 13:15:23 -07004205 pRoamProfile->ChannelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 pRoamProfile->ChannelInfo.numOfChannels = 0;
4207 }
4208 else
4209 {
4210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4211 return -EINVAL;
4212 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004213
4214 if( WLAN_HDD_INFRA_STATION == pAdapter->device_mode )
4215 {
4216 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState =
4217 eConnectionState_Connecting;
4218 }
4219
4220 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004221 return status;
4222}
4223
4224/*
4225 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4226 * This function is used to set the authentication type (OPEN/SHARED).
4227 *
4228 */
4229static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4230 enum nl80211_auth_type auth_type)
4231{
4232 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4233 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4234
4235 ENTER();
4236
4237 /*set authentication type*/
4238 switch (auth_type)
4239 {
4240 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4241 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004242#ifdef WLAN_FEATURE_VOWIFI_11R
4243 case NL80211_AUTHTYPE_FT:
4244#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004245 hddLog(VOS_TRACE_LEVEL_INFO,
4246 "%s: set authentication type to OPEN", __func__);
4247 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4248 break;
4249
4250 case NL80211_AUTHTYPE_SHARED_KEY:
4251 hddLog(VOS_TRACE_LEVEL_INFO,
4252 "%s: set authentication type to SHARED", __func__);
4253 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4254 break;
4255#ifdef FEATURE_WLAN_CCX
4256 case NL80211_AUTHTYPE_NETWORK_EAP:
4257 hddLog(VOS_TRACE_LEVEL_INFO,
4258 "%s: set authentication type to CCKM WPA", __func__);
4259 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4260 break;
4261#endif
4262
4263
4264 default:
4265 hddLog(VOS_TRACE_LEVEL_ERROR,
4266 "%s: Unsupported authentication type %d", __func__,
4267 auth_type);
4268 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4269 return -EINVAL;
4270 }
4271
4272 pWextState->roamProfile.AuthType.authType[0] =
4273 pHddStaCtx->conn_info.authType;
4274 return 0;
4275}
4276
4277/*
4278 * FUNCTION: wlan_hdd_set_akm_suite
4279 * This function is used to set the key mgmt type(PSK/8021x).
4280 *
4281 */
4282static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4283 u32 key_mgmt
4284 )
4285{
4286 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4287 ENTER();
4288
4289 /*set key mgmt type*/
4290 switch(key_mgmt)
4291 {
4292 case WLAN_AKM_SUITE_PSK:
4293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4294 __func__);
4295 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4296 break;
4297
4298 case WLAN_AKM_SUITE_8021X:
4299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4300 __func__);
4301 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4302 break;
4303#ifdef FEATURE_WLAN_CCX
4304#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4305#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4306 case WLAN_AKM_SUITE_CCKM:
4307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4308 __func__);
4309 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4310 break;
4311#endif
4312
4313 default:
4314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4315 __func__, key_mgmt);
4316 return -EINVAL;
4317
4318 }
4319 return 0;
4320}
4321
4322/*
4323 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4324 * This function is used to set the encryption type
4325 * (NONE/WEP40/WEP104/TKIP/CCMP).
4326 */
4327static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4328 u32 cipher,
4329 bool ucast
4330 )
4331{
4332 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4333 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4334 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4335
4336 ENTER();
4337
4338 if (!cipher)
4339 {
4340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4341 __func__, cipher);
4342 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4343 }
4344 else
4345 {
4346
4347 /*set encryption method*/
4348 switch (cipher)
4349 {
4350 case IW_AUTH_CIPHER_NONE:
4351 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4352 break;
4353
4354 case WLAN_CIPHER_SUITE_WEP40:
4355 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4356 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4357 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4358 else
4359 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4360 break;
4361
4362 case WLAN_CIPHER_SUITE_WEP104:
4363 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4364 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4365 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4366 else
4367 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4368 break;
4369
4370 case WLAN_CIPHER_SUITE_TKIP:
4371 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4372 break;
4373
4374 case WLAN_CIPHER_SUITE_CCMP:
4375 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4376 break;
4377#ifdef FEATURE_WLAN_WAPI
4378 case WLAN_CIPHER_SUITE_SMS4:
4379 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4380 break;
4381#endif
4382
4383#ifdef FEATURE_WLAN_CCX
4384 case WLAN_CIPHER_SUITE_KRK:
4385 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4386 break;
4387#endif
4388 default:
4389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4390 __func__, cipher);
4391 return -EOPNOTSUPP;
4392 }
4393 }
4394
4395 if (ucast)
4396 {
4397 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4398 __func__, encryptionType);
4399 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4400 pWextState->roamProfile.EncryptionType.numEntries = 1;
4401 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4402 encryptionType;
4403 }
4404 else
4405 {
4406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4407 __func__, encryptionType);
4408 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4409 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4410 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4411 }
4412
4413 return 0;
4414}
4415
4416
4417/*
4418 * FUNCTION: wlan_hdd_cfg80211_set_ie
4419 * This function is used to parse WPA/RSN IE's.
4420 */
4421int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4422 u8 *ie,
4423 size_t ie_len
4424 )
4425{
4426 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4427 u8 *genie = ie;
4428 v_U16_t remLen = ie_len;
4429#ifdef FEATURE_WLAN_WAPI
4430 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4431 u16 *tmp;
4432 v_U16_t akmsuiteCount;
4433 int *akmlist;
4434#endif
4435 ENTER();
4436
4437 /* clear previous assocAddIE */
4438 pWextState->assocAddIE.length = 0;
4439 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4440
4441 while (remLen >= 2)
4442 {
4443 v_U16_t eLen = 0;
4444 v_U8_t elementId;
4445 elementId = *genie++;
4446 eLen = *genie++;
4447 remLen -= 2;
4448
4449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4450 __func__, elementId, eLen);
4451
4452 switch ( elementId )
4453 {
4454 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004455 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 -07004456 {
4457 hddLog(VOS_TRACE_LEVEL_ERROR,
4458 "%s: Invalid WPA IE", __func__);
4459 return -EINVAL;
4460 }
4461 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4462 {
4463 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4464 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4465 __func__, eLen + 2);
4466
4467 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4468 {
4469 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE. "
4470 "Need bigger buffer space\n");
4471 VOS_ASSERT(0);
4472 return -ENOMEM;
4473 }
4474 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4475 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4476 pWextState->assocAddIE.length += eLen + 2;
4477
4478 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4479 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4480 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4481 }
4482 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4483 {
4484 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4485 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4486 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4487 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4488 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4489 }
4490#ifdef WLAN_FEATURE_P2P
4491 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4492 P2P_OUI_TYPE_SIZE))
4493 /*Consider P2P IE, only for P2P Client */
4494 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4495 {
4496 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4497 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4498 __func__, eLen + 2);
4499
4500 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4501 {
4502 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4503 "Need bigger buffer space\n");
4504 VOS_ASSERT(0);
4505 return -ENOMEM;
4506 }
4507 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4508 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4509 pWextState->assocAddIE.length += eLen + 2;
4510
4511 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4512 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4513 }
4514#endif
4515#ifdef WLAN_FEATURE_WFD
4516 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4517 WFD_OUI_TYPE_SIZE))
4518 /*Consider WFD IE, only for P2P Client */
4519 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4520 {
4521 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4522 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4523 __func__, eLen + 2);
4524
4525 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4526 {
4527 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4528 "Need bigger buffer space\n");
4529 VOS_ASSERT(0);
4530 return -ENOMEM;
4531 }
4532 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4533 // WPS IE + P2P IE + WFD IE
4534 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4535 pWextState->assocAddIE.length += eLen + 2;
4536
4537 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4538 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4539 }
4540#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004541 /* Appending HS 2.0 Indication Element in Assiciation Request */
4542 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004543 HS20_OUI_TYPE_SIZE)) )
4544 {
4545 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4546 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4547 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004548
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004549 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4550 {
4551 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4552 "Need bigger buffer space\n");
4553 VOS_ASSERT(0);
4554 return -ENOMEM;
4555 }
4556 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4557 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004558
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004559 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4560 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4561 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004562
Jeff Johnson295189b2012-06-20 16:38:30 -07004563 break;
4564 case DOT11F_EID_RSN:
4565 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4566 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4567 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4568 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4569 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4570 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004571 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4572 case DOT11F_EID_EXTCAP:
4573 {
4574 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4575 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
4576 __func__, eLen + 2);
4577
4578 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4579 {
4580 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4581 "Need bigger buffer space\n");
4582 VOS_ASSERT(0);
4583 return -ENOMEM;
4584 }
4585 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4586 pWextState->assocAddIE.length += eLen + 2;
4587
4588 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4589 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4590 break;
4591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004592#ifdef FEATURE_WLAN_WAPI
4593 case WLAN_EID_WAPI:
4594 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
4595 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
4596 pAdapter->wapi_info.nWapiMode);
4597 tmp = (u16 *)ie;
4598 tmp = tmp + 2; // Skip element Id and Len, Version
4599 akmsuiteCount = WPA_GET_LE16(tmp);
4600 tmp = tmp + 1;
4601 akmlist = (int *)(tmp);
4602 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
4603 {
4604 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
4605 }
4606 else
4607 {
4608 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
4609 VOS_ASSERT(0);
4610 return -EINVAL;
4611 }
4612
4613 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
4614 {
4615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004616 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004617 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
4618 }
4619 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
4620 {
4621 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004622 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004623 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
4624 }
4625 break;
4626#endif
4627 default:
4628 hddLog (VOS_TRACE_LEVEL_ERROR,
4629 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004630 /* when Unknown IE is received we should break and continue
4631 * to the next IE in the buffer instead we were returning
4632 * so changing this to break */
4633 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07004634 }
4635 genie += eLen;
4636 remLen -= eLen;
4637 }
4638 EXIT();
4639 return 0;
4640}
4641
4642/*
4643 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4644 * This function is used to initialize the security
4645 * parameters during connect operation.
4646 */
4647int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
4648 struct cfg80211_connect_params *req
4649 )
4650{
4651 int status = 0;
4652 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4653 ENTER();
4654
4655 /*set wpa version*/
4656 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4657
4658 if (req->crypto.wpa_versions)
4659 {
4660 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
4661 && ( (req->ie_len)
4662 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
4663 // Make sure that it is including a WPA IE.
4664 /* Currently NL is putting WPA version 1 even for open,
4665 * since p2p ie is also put in same buffer.
4666 * */
4667 {
4668 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
4669 }
4670 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
4671 {
4672 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
4673 }
4674 }
4675
4676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
4677 pWextState->wpaVersion);
4678
4679 /*set authentication type*/
4680 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
4681
4682 if (0 > status)
4683 {
4684 hddLog(VOS_TRACE_LEVEL_ERROR,
4685 "%s: failed to set authentication type ", __func__);
4686 return status;
4687 }
4688
4689 /*set key mgmt type*/
4690 if (req->crypto.n_akm_suites)
4691 {
4692 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
4693 if (0 > status)
4694 {
4695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
4696 __func__);
4697 return status;
4698 }
4699 }
4700
4701 /*set pairwise cipher type*/
4702 if (req->crypto.n_ciphers_pairwise)
4703 {
4704 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
4705 req->crypto.ciphers_pairwise[0], true);
4706 if (0 > status)
4707 {
4708 hddLog(VOS_TRACE_LEVEL_ERROR,
4709 "%s: failed to set unicast cipher type", __func__);
4710 return status;
4711 }
4712 }
4713 else
4714 {
4715 /*Reset previous cipher suite to none*/
4716 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
4717 if (0 > status)
4718 {
4719 hddLog(VOS_TRACE_LEVEL_ERROR,
4720 "%s: failed to set unicast cipher type", __func__);
4721 return status;
4722 }
4723 }
4724
4725 /*set group cipher type*/
4726 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
4727 false);
4728
4729 if (0 > status)
4730 {
4731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
4732 __func__);
4733 return status;
4734 }
4735
4736 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
4737 if (req->ie_len)
4738 {
4739 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
4740 if ( 0 > status)
4741 {
4742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
4743 __func__);
4744 return status;
4745 }
4746 }
4747
4748 /*incase of WEP set default key information*/
4749 if (req->key && req->key_len)
4750 {
4751 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
4752 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
4753 )
4754 {
4755 if ( IW_AUTH_KEY_MGMT_802_1X
4756 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
4757 {
4758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
4759 __func__);
4760 return -EOPNOTSUPP;
4761 }
4762 else
4763 {
4764 u8 key_len = req->key_len;
4765 u8 key_idx = req->key_idx;
4766
4767 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
4768 && (CSR_MAX_NUM_KEY > key_idx)
4769 )
4770 {
4771 hddLog(VOS_TRACE_LEVEL_INFO,
4772 "%s: setting default wep key, key_idx = %hu key_len %hu",
4773 __func__, key_idx, key_len);
4774 vos_mem_copy(
4775 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
4776 req->key, key_len);
4777 pWextState->roamProfile.Keys.KeyLength[key_idx] =
4778 (u8)key_len;
4779 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
4780 }
4781 }
4782 }
4783 }
4784
4785 return status;
4786}
4787
4788/*
4789 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4790 * This function is used to initialize the security
4791 * parameters during connect operation.
4792 */
4793static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
4794 struct net_device *ndev,
4795 struct cfg80211_connect_params *req
4796 )
4797{
4798 int status = 0;
4799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4800 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
4801 hdd_context_t *pHddCtx = NULL;
4802
4803 ENTER();
4804
4805 hddLog(VOS_TRACE_LEVEL_INFO,
4806 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
4807
4808 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
4809 {
4810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4811 "%s:LOGP in Progress. Ignore!!!", __func__);
4812 return -EAGAIN;
4813 }
4814
4815#ifdef WLAN_BTAMP_FEATURE
4816 //Infra connect not supported when AMP traffic is on.
4817 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
4818 {
4819 hddLog(VOS_TRACE_LEVEL_ERROR,
4820 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004821 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07004822 }
4823#endif
4824 /*initialise security parameters*/
4825 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
4826
4827 if ( 0 > status)
4828 {
4829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
4830 __func__);
4831 return status;
4832 }
4833
4834 //If Device Mode is Station Concurrent Sessions Exit BMps
4835 //P2P Mode will be taken care in Open/close adaptor
4836 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4837 (vos_concurrent_sessions_running()))
4838 {
4839 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
4840
4841 if (NULL != pVosContext)
4842 {
4843 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
4844 if(NULL != pHddCtx)
4845 {
4846 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
4847 }
4848 }
4849 }
4850
Mohit Khanna765234a2012-09-11 15:08:35 -07004851 if ( req->channel )
4852 {
4853 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
4854 req->ssid_len, req->bssid,
4855 req->channel->hw_value);
4856 }
4857 else
4858 {
4859 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
4860 req->ssid_len, req->bssid,
4861 0);
4862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004863
4864 if (0 > status)
4865 {
4866 //ReEnable BMPS if disabled
4867 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
4868 (NULL != pHddCtx))
4869 {
4870 //ReEnable Bmps and Imps back
4871 hdd_enable_bmps_imps(pHddCtx);
4872 }
4873
4874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
4875 return status;
4876 }
4877 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
4878 EXIT();
4879 return status;
4880}
4881
4882
4883/*
4884 * FUNCTION: wlan_hdd_cfg80211_disconnect
4885 * This function is used to issue a disconnect request to SME
4886 */
4887static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
4888 struct net_device *dev,
4889 u16 reason
4890 )
4891{
4892 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4893 tCsrRoamProfile *pRoamProfile =
4894 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
4895 int status = 0;
4896 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4897
4898 ENTER();
4899
4900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4901 __func__,pAdapter->device_mode);
4902
4903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
4904 __func__, reason);
4905
4906 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4907 {
4908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4909 "%s:LOGP in Progress. Ignore!!!",__func__);
4910 return -EAGAIN;
4911 }
4912 if (NULL != pRoamProfile)
4913 {
4914 /*issue disconnect request to SME, if station is in connected state*/
4915 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
4916 {
4917 eCsrRoamDisconnectReason reasonCode =
4918 eCSR_DISCONNECT_REASON_UNSPECIFIED;
4919 switch(reason)
4920 {
4921 case WLAN_REASON_MIC_FAILURE:
4922 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
4923 break;
4924
4925 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
4926 case WLAN_REASON_DISASSOC_AP_BUSY:
4927 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
4928 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
4929 break;
4930
4931 case WLAN_REASON_PREV_AUTH_NOT_VALID:
4932 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
4933 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
4934 break;
4935
4936 case WLAN_REASON_DEAUTH_LEAVING:
4937 default:
4938 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
4939 break;
4940 }
4941 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
4942 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
4943 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4944
4945 /*issue disconnect*/
4946 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4947 pAdapter->sessionId, reasonCode);
4948
4949 if ( 0 != status)
4950 {
4951 hddLog(VOS_TRACE_LEVEL_ERROR,
4952 "%s csrRoamDisconnect failure, returned %d \n",
4953 __func__, (int)status );
4954 return -EINVAL;
4955 }
4956
4957 wait_for_completion_interruptible_timeout(
4958 &pAdapter->disconnect_comp_var,
4959 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4960
4961
4962 /*stop tx queues*/
4963 netif_tx_disable(dev);
4964 netif_carrier_off(dev);
4965 }
4966 }
4967 else
4968 {
4969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
4970 }
4971
4972 return status;
4973}
4974
4975/*
4976 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
4977 * This function is used to initialize the security
4978 * settings in IBSS mode.
4979 */
4980static int wlan_hdd_cfg80211_set_privacy_ibss(
4981 hdd_adapter_t *pAdapter,
4982 struct cfg80211_ibss_params *params
4983 )
4984{
4985 int status = 0;
4986 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4987 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4988 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4989
4990 ENTER();
4991
4992 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4993
4994 if (params->ie_len && ( NULL != params->ie) )
4995 {
4996 if (WLAN_EID_RSN == params->ie[0])
4997 {
4998 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
4999 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5000 }
5001 else
5002 {
5003 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5004 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5005 }
5006 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5007
5008 if (0 > status)
5009 {
5010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5011 __func__);
5012 return status;
5013 }
5014 }
5015
5016 pWextState->roamProfile.AuthType.authType[0] =
5017 pHddStaCtx->conn_info.authType =
5018 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5019
5020 if (params->privacy)
5021 {
5022 /* Security enabled IBSS, At this time there is no information available
5023 * about the security paramters, so initialise the encryption type to
5024 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5025 * The correct security parameters will be updated later in
5026 * wlan_hdd_cfg80211_add_key */
5027 /* Hal expects encryption type to be set inorder
5028 *enable privacy bit in beacons */
5029
5030 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5031 }
5032
5033 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5034 pWextState->roamProfile.EncryptionType.numEntries = 1;
5035 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5036
5037 return status;
5038}
5039
5040/*
5041 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5042 * This function is used to create/join an IBSS
5043 */
5044static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5045 struct net_device *dev,
5046 struct cfg80211_ibss_params *params
5047 )
5048{
5049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5050 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5051 tCsrRoamProfile *pRoamProfile;
5052 int status;
5053 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5054
5055 ENTER();
5056
5057 hddLog(VOS_TRACE_LEVEL_INFO,
5058 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5059
5060 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5061 {
5062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5063 "%s:LOGP in Progress. Ignore!!!", __func__);
5064 return -EAGAIN;
5065 }
5066
5067 if (NULL == pWextState)
5068 {
5069 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5070 __func__);
5071 return -EIO;
5072 }
5073
5074 pRoamProfile = &pWextState->roamProfile;
5075
5076 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5077 {
5078 hddLog (VOS_TRACE_LEVEL_ERROR,
5079 "%s Interface type is not set to IBSS \n", __func__);
5080 return -EINVAL;
5081 }
5082
5083 /* Set Channel */
5084 if (NULL != params->channel)
5085 {
5086 u8 channelNum;
5087 if (IEEE80211_BAND_5GHZ == params->channel->band)
5088 {
5089 hddLog(VOS_TRACE_LEVEL_ERROR,
5090 "%s: IBSS join is called with unsupported band %d",
5091 __func__, params->channel->band);
5092 return -EOPNOTSUPP;
5093 }
5094
5095 /* Get channel number */
5096 channelNum =
5097 ieee80211_frequency_to_channel(params->channel->center_freq);
5098
5099 /*TODO: use macro*/
5100 if (14 >= channelNum)
5101 {
5102 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5103 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5104 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5105 int indx;
5106
5107 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5108 validChan, &numChans))
5109 {
5110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5111 __func__);
5112 return -EOPNOTSUPP;
5113 }
5114
5115 for (indx = 0; indx < numChans; indx++)
5116 {
5117 if (channelNum == validChan[indx])
5118 {
5119 break;
5120 }
5121 }
5122 if (indx >= numChans)
5123 {
5124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5125 __func__, channelNum);
5126 return -EINVAL;
5127 }
5128 /* Set the Operational Channel */
5129 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5130 channelNum);
5131 pRoamProfile->ChannelInfo.numOfChannels = 1;
5132 pHddStaCtx->conn_info.operationChannel = channelNum;
5133 pRoamProfile->ChannelInfo.ChannelList =
5134 &pHddStaCtx->conn_info.operationChannel;
5135 }
5136 else
5137 {
5138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5139 __func__, channelNum);
5140 return -EINVAL;
5141 }
5142 }
5143
5144 /* Initialize security parameters */
5145 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5146 if (status < 0)
5147 {
5148 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5149 __func__);
5150 return status;
5151 }
5152
5153 /* Issue connect start */
5154 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005155 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005156
5157 if (0 > status)
5158 {
5159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5160 return status;
5161 }
5162
5163 return 0;
5164}
5165
5166/*
5167 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5168 * This function is used to leave an IBSS
5169 */
5170static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5171 struct net_device *dev
5172 )
5173{
5174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5175 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5176 tCsrRoamProfile *pRoamProfile;
5177
5178 ENTER();
5179
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005180 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5181 {
5182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5183 "%s:LOGP in Progress. Ignore!!!", __func__);
5184 return -EAGAIN;
5185 }
5186
Jeff Johnson295189b2012-06-20 16:38:30 -07005187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5188 if (NULL == pWextState)
5189 {
5190 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5191 __func__);
5192 return -EIO;
5193 }
5194
5195 pRoamProfile = &pWextState->roamProfile;
5196
5197 /* Issue disconnect only if interface type is set to IBSS */
5198 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5199 {
5200 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5201 __func__);
5202 return -EINVAL;
5203 }
5204
5205 /* Issue Disconnect request */
5206 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5207 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5208 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5209
5210 return 0;
5211}
5212
5213/*
5214 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5215 * This function is used to set the phy parameters
5216 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5217 */
5218static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5219 u32 changed)
5220{
5221 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5222 tHalHandle hHal = pHddCtx->hHal;
5223
5224 ENTER();
5225
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005226 if ( pHddCtx->isLogpInProgress )
5227 {
5228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5229 "%s:LOGP in Progress. Ignore!!!", __func__);
5230 return -EAGAIN;
5231 }
5232
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5234 {
5235 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5236 WNI_CFG_RTS_THRESHOLD_STAMAX :
5237 wiphy->rts_threshold;
5238
5239 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5240 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5241 {
5242 hddLog(VOS_TRACE_LEVEL_ERROR,
5243 "%s: Invalid RTS Threshold value %hu",
5244 __func__, rts_threshold);
5245 return -EINVAL;
5246 }
5247
5248 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5249 rts_threshold, ccmCfgSetCallback,
5250 eANI_BOOLEAN_TRUE))
5251 {
5252 hddLog(VOS_TRACE_LEVEL_ERROR,
5253 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5254 __func__, rts_threshold);
5255 return -EIO;
5256 }
5257
5258 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5259 rts_threshold);
5260 }
5261
5262 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5263 {
5264 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5265 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5266 wiphy->frag_threshold;
5267
5268 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5269 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5270 {
5271 hddLog(VOS_TRACE_LEVEL_ERROR,
5272 "%s: Invalid frag_threshold value %hu", __func__,
5273 frag_threshold);
5274 return -EINVAL;
5275 }
5276
5277 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5278 frag_threshold, ccmCfgSetCallback,
5279 eANI_BOOLEAN_TRUE))
5280 {
5281 hddLog(VOS_TRACE_LEVEL_ERROR,
5282 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5283 __func__, frag_threshold);
5284 return -EIO;
5285 }
5286
5287 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5288 frag_threshold);
5289 }
5290
5291 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5292 || (changed & WIPHY_PARAM_RETRY_LONG))
5293 {
5294 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5295 wiphy->retry_short :
5296 wiphy->retry_long;
5297
5298 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5299 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5300 {
5301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5302 __func__, retry_value);
5303 return -EINVAL;
5304 }
5305
5306 if (changed & WIPHY_PARAM_RETRY_SHORT)
5307 {
5308 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5309 retry_value, ccmCfgSetCallback,
5310 eANI_BOOLEAN_TRUE))
5311 {
5312 hddLog(VOS_TRACE_LEVEL_ERROR,
5313 "%s: ccmCfgSetInt failed for long retry count %hu",
5314 __func__, retry_value);
5315 return -EIO;
5316 }
5317 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5318 __func__, retry_value);
5319 }
5320 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5321 {
5322 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5323 retry_value, ccmCfgSetCallback,
5324 eANI_BOOLEAN_TRUE))
5325 {
5326 hddLog(VOS_TRACE_LEVEL_ERROR,
5327 "%s: ccmCfgSetInt failed for short retry count %hu",
5328 __func__, retry_value);
5329 return -EIO;
5330 }
5331 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5332 __func__, retry_value);
5333 }
5334 }
5335
5336 return 0;
5337}
5338
5339/*
5340 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5341 * This function is used to set the txpower
5342 */
5343static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5344#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5345 enum tx_power_setting type,
5346#else
5347 enum nl80211_tx_power_setting type,
5348#endif
5349 int dbm)
5350{
5351 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5352 tHalHandle hHal = pHddCtx->hHal;
5353 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5354 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5355
5356 ENTER();
5357
5358 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5359 dbm, ccmCfgSetCallback,
5360 eANI_BOOLEAN_TRUE))
5361 {
5362 hddLog(VOS_TRACE_LEVEL_ERROR,
5363 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5364 return -EIO;
5365 }
5366
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005367 if ( pHddCtx->isLogpInProgress )
5368 {
5369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5370 "%s:LOGP in Progress. Ignore!!!", __func__);
5371 return -EAGAIN;
5372 }
5373
Jeff Johnson295189b2012-06-20 16:38:30 -07005374 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5375 dbm);
5376
5377 switch(type)
5378 {
5379 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5380 /* Fall through */
5381 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5382 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5383 {
5384 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5385 __func__);
5386 return -EIO;
5387 }
5388 break;
5389 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5391 __func__);
5392 return -EOPNOTSUPP;
5393 break;
5394 default:
5395 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5396 __func__, type);
5397 return -EIO;
5398 }
5399
5400 return 0;
5401}
5402
5403/*
5404 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5405 * This function is used to read the txpower
5406 */
5407static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5408{
5409
5410 hdd_adapter_t *pAdapter;
5411 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5412
Jeff Johnsone7245742012-09-05 17:12:55 -07005413 ENTER();
5414
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 if (NULL == pHddCtx)
5416 {
5417 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5418 *dbm = 0;
5419 return -ENOENT;
5420 }
5421
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005422 if ( pHddCtx->isLogpInProgress )
5423 {
5424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5425 "%s:LOGP in Progress. Ignore!!!", __func__);
5426 return -EAGAIN;
5427 }
5428
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5430 if (NULL == pAdapter)
5431 {
5432 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5433 return -ENOENT;
5434 }
5435
5436 wlan_hdd_get_classAstats(pAdapter);
5437 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5438
Jeff Johnsone7245742012-09-05 17:12:55 -07005439 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 return 0;
5441}
5442
5443static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5444 u8* mac, struct station_info *sinfo)
5445{
5446 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5447 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5448 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5449 tANI_U8 rate_flags;
5450
5451 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5452 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5453 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5454
5455 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5456 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5457 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5458 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5459 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5460 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5461 tANI_U16 maxRate = 0;
5462 tANI_U16 myRate;
5463 tANI_U16 currentRate = 0;
5464 tANI_U8 maxSpeedMCS = 0;
5465 tANI_U8 maxMCSIdx = 0;
5466 tANI_U8 rateFlag = 1;
5467 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005468 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005469
Jeff Johnsone7245742012-09-05 17:12:55 -07005470 ENTER();
5471
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5473 (0 == ssidlen))
5474 {
5475 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5476 " Invalid ssidlen, %d", __func__, ssidlen);
5477 /*To keep GUI happy*/
5478 return 0;
5479 }
5480
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005481 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5482 {
5483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5484 "%s:LOGP in Progress. Ignore!!!", __func__);
5485 return -EAGAIN;
5486 }
5487
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5489 sinfo->filled |= STATION_INFO_SIGNAL;
5490
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005491 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5493
5494 //convert to the UI units of 100kbps
5495 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5496
5497#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005498 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 -07005499 sinfo->signal,
5500 pCfg->reportMaxLinkSpeed,
5501 myRate,
5502 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005503 (int) pCfg->linkSpeedRssiMid,
5504 (int) pCfg->linkSpeedRssiLow,
5505 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005506#endif //LINKSPEED_DEBUG_ENABLED
5507
5508 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5509 {
5510 // we do not want to necessarily report the current speed
5511 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5512 {
5513 // report the max possible speed
5514 rssidx = 0;
5515 }
5516 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5517 {
5518 // report the max possible speed with RSSI scaling
5519 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5520 {
5521 // report the max possible speed
5522 rssidx = 0;
5523 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005524 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 {
5526 // report middle speed
5527 rssidx = 1;
5528 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005529 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5530 {
5531 // report middle speed
5532 rssidx = 2;
5533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 else
5535 {
5536 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005537 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 }
5539 }
5540 else
5541 {
5542 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5543 hddLog(VOS_TRACE_LEVEL_ERROR,
5544 "%s: Invalid value for reportMaxLinkSpeed: %u",
5545 __func__, pCfg->reportMaxLinkSpeed);
5546 rssidx = 0;
5547 }
5548
5549 maxRate = 0;
5550
5551 /* Get Basic Rate Set */
5552 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5553 for (i = 0; i < ORLeng; i++)
5554 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005555 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 {
5557 /* Validate Rate Set */
5558 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5559 {
5560 currentRate = supported_data_rate[j].supported_rate[rssidx];
5561 break;
5562 }
5563 }
5564 /* Update MAX rate */
5565 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5566 }
5567
5568 /* Get Extended Rate Set */
5569 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5570 for (i = 0; i < ERLeng; i++)
5571 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005572 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005573 {
5574 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
5575 {
5576 currentRate = supported_data_rate[j].supported_rate[rssidx];
5577 break;
5578 }
5579 }
5580 /* Update MAX rate */
5581 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5582 }
5583
5584 /* Get MCS Rate Set -- but only if we are connected at MCS
5585 rates or if we are always reporting max speed or if we have
5586 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005587 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 {
5589 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
5590 rateFlag = 0;
5591 if (rate_flags & eHAL_TX_RATE_HT40)
5592 {
5593 rateFlag |= 1;
5594 }
5595 if (rate_flags & eHAL_TX_RATE_SGI)
5596 {
5597 rateFlag |= 2;
5598 }
5599
5600 for (i = 0; i < MCSLeng; i++)
5601 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005602 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
5603 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 {
5605 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
5606 {
5607 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
5608 break;
5609 }
5610 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005611 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 {
5613 maxRate = currentRate;
5614 maxSpeedMCS = 1;
5615 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
5616 }
5617 }
5618 }
5619
5620 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005621 if (((maxRate < myRate) && (0 == rssidx)) ||
5622 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 {
5624 maxRate = myRate;
5625 if (rate_flags & eHAL_TX_RATE_LEGACY)
5626 {
5627 maxSpeedMCS = 0;
5628 }
5629 else
5630 {
5631 maxSpeedMCS = 1;
5632 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5633 }
5634 }
5635
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005636 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 {
5638 sinfo->txrate.legacy = maxRate;
5639#ifdef LINKSPEED_DEBUG_ENABLED
5640 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
5641#endif //LINKSPEED_DEBUG_ENABLED
5642 }
5643 else
5644 {
5645 sinfo->txrate.mcs = maxMCSIdx;
5646 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5647 if (rate_flags & eHAL_TX_RATE_SGI)
5648 {
5649 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5650 }
5651 if (rate_flags & eHAL_TX_RATE_HT40)
5652 {
5653 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5654 }
5655#ifdef LINKSPEED_DEBUG_ENABLED
5656 pr_info("Reporting MCS rate %d flags %x\n",
5657 sinfo->txrate.mcs,
5658 sinfo->txrate.flags );
5659#endif //LINKSPEED_DEBUG_ENABLED
5660 }
5661 }
5662 else
5663 {
5664 // report current rate instead of max rate
5665
5666 if (rate_flags & eHAL_TX_RATE_LEGACY)
5667 {
5668 //provide to the UI in units of 100kbps
5669 sinfo->txrate.legacy = myRate;
5670#ifdef LINKSPEED_DEBUG_ENABLED
5671 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
5672#endif //LINKSPEED_DEBUG_ENABLED
5673 }
5674 else
5675 {
5676 //must be MCS
5677 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5678 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5679 if (rate_flags & eHAL_TX_RATE_SGI)
5680 {
5681 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5682 }
5683 if (rate_flags & eHAL_TX_RATE_HT40)
5684 {
5685 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5686 }
5687#ifdef LINKSPEED_DEBUG_ENABLED
5688 pr_info("Reporting actual MCS rate %d flags %x\n",
5689 sinfo->txrate.mcs,
5690 sinfo->txrate.flags );
5691#endif //LINKSPEED_DEBUG_ENABLED
5692 }
5693 }
5694 sinfo->filled |= STATION_INFO_TX_BITRATE;
5695
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005696 sinfo->tx_packets =
5697 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
5698 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
5699 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
5700 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
5701
5702 sinfo->tx_retries =
5703 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
5704 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
5705 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
5706 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
5707
5708 sinfo->tx_failed =
5709 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
5710 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
5711 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
5712 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
5713
5714 sinfo->filled |=
5715 STATION_INFO_TX_PACKETS |
5716 STATION_INFO_TX_RETRIES |
5717 STATION_INFO_TX_FAILED;
5718
5719 EXIT();
5720 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005721}
5722
5723static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
5724 struct net_device *dev, bool mode, v_SINT_t timeout)
5725{
5726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5727 VOS_STATUS vos_status;
5728
Jeff Johnsone7245742012-09-05 17:12:55 -07005729 ENTER();
5730
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 if (NULL == pAdapter)
5732 {
5733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5734 return -ENODEV;
5735 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005736 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5737 {
5738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5739 "%s:LOGP in Progress. Ignore!!!", __func__);
5740 return -EAGAIN;
5741 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005742
5743 /**The get power cmd from the supplicant gets updated by the nl only
5744 *on successful execution of the function call
5745 *we are oppositely mapped w.r.t mode in the driver
5746 **/
5747 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
5748
Jeff Johnsone7245742012-09-05 17:12:55 -07005749 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 if (VOS_STATUS_E_FAILURE == vos_status)
5751 {
5752 return -EINVAL;
5753 }
5754 return 0;
5755}
5756
5757
5758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5759static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
5760 struct net_device *netdev,
5761 u8 key_index)
5762{
Jeff Johnsone7245742012-09-05 17:12:55 -07005763 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 return 0;
5765}
5766#endif //LINUX_VERSION_CODE
5767
5768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5769static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5770 struct net_device *dev,
5771 struct ieee80211_txq_params *params)
5772{
Jeff Johnsone7245742012-09-05 17:12:55 -07005773 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 return 0;
5775}
5776#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5777static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5778 struct ieee80211_txq_params *params)
5779{
Jeff Johnsone7245742012-09-05 17:12:55 -07005780 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 return 0;
5782}
5783#endif //LINUX_VERSION_CODE
5784
5785static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
5786 struct net_device *dev, u8 *mac)
5787{
5788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5789
Jeff Johnsone7245742012-09-05 17:12:55 -07005790 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
5792 {
5793 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
5794 return -EINVAL;
5795 }
5796
5797 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
5798 {
5799 hddLog( LOGE,
5800 "%s: Wlan Load/Unload is in progress", __func__);
5801 return -EBUSY;
5802 }
5803
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005804 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5805 {
5806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5807 "%s:LOGP in Progress. Ignore!!!", __func__);
5808 return -EAGAIN;
5809 }
5810
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
5812#ifdef WLAN_FEATURE_P2P
5813 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5814#endif
5815 )
5816 {
5817 if( NULL == mac )
5818 {
5819 v_U16_t i;
5820 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
5821 {
5822 if(pAdapter->aStaInfo[i].isUsed)
5823 {
5824 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
5825 hddLog(VOS_TRACE_LEVEL_INFO,
5826 "%s: Delete STA with MAC::"
5827 "%02x:%02x:%02x:%02x:%02x:%02x",
5828 __func__,
5829 macAddr[0], macAddr[1], macAddr[2],
5830 macAddr[3], macAddr[4], macAddr[5]);
5831 hdd_softap_sta_deauth(pAdapter, macAddr);
5832 }
5833 }
5834 }
5835 else
5836 {
5837 hddLog(VOS_TRACE_LEVEL_INFO,
5838 "%s: Delete STA with MAC::"
5839 "%02x:%02x:%02x:%02x:%02x:%02x",
5840 __func__,
5841 mac[0], mac[1], mac[2],
5842 mac[3], mac[4], mac[5]);
5843 hdd_softap_sta_deauth(pAdapter, mac);
5844 }
5845 }
5846
5847 EXIT();
5848
5849 return 0;
5850}
5851
5852static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
5853 struct net_device *dev, u8 *mac, struct station_parameters *params)
5854{
5855 // TODO: Implement this later.
Jeff Johnsone7245742012-09-05 17:12:55 -07005856 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 return 0;
5858}
5859
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005860
5861#ifdef FEATURE_WLAN_LFR
5862static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07005863 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005864{
5865#define MAX_PMKSAIDS_IN_CACHE 8
5866 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07005867 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005868 tANI_U32 j=0;
5869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5870 tHalHandle halHandle;
5871 eHalStatus result;
5872 tANI_U8 BSSIDMatched = 0;
5873
Jeff Johnsone7245742012-09-05 17:12:55 -07005874 ENTER();
5875
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005876 // Validate pAdapter
5877 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
5878 {
5879 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
5880 return -EINVAL;
5881 }
5882
5883 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
5884 {
5885 hddLog( LOGE,
5886 "%s: Wlan Load/Unload is in progress", __func__);
5887 return -EBUSY;
5888 }
5889
5890 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5891 {
5892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5893 "%s:LOGP in Progress. Ignore!!!", __func__);
5894 return -EAGAIN;
5895 }
5896
5897 // Retrieve halHandle
5898 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5899
5900 for (j = 0; j < i; j++)
5901 {
5902 if(vos_mem_compare(PMKIDCache[j].BSSID,
5903 pmksa->bssid, WNI_CFG_BSSID_LEN))
5904 {
5905 /* BSSID matched previous entry. Overwrite it. */
5906 BSSIDMatched = 1;
5907 vos_mem_copy(PMKIDCache[j].BSSID,
5908 pmksa->bssid, WNI_CFG_BSSID_LEN);
5909 vos_mem_copy(PMKIDCache[j].PMKID,
5910 pmksa->pmkid,
5911 CSR_RSN_PMKID_SIZE);
5912 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005913 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005914 dump_bssid(pmksa->bssid);
5915 dump_pmkid(halHandle, pmksa->pmkid);
5916 break;
5917 }
5918 }
5919
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07005920 /* Check we compared all entries,if then take the first slot now */
5921 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
5922
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005923 if (!BSSIDMatched)
5924 {
5925 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
5926 vos_mem_copy(PMKIDCache[i].BSSID,
5927 pmksa->bssid, ETHER_ADDR_LEN);
5928 vos_mem_copy(PMKIDCache[i].PMKID,
5929 pmksa->pmkid,
5930 CSR_RSN_PMKID_SIZE);
5931 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005932 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005933 dump_bssid(pmksa->bssid);
5934 dump_pmkid(halHandle, pmksa->pmkid);
5935 // Increment the HDD Local Cache index
5936 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
5937 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
5938 }
5939
5940
5941 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
5942 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005943 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005944 hddLog(VOS_TRACE_LEVEL_FATAL, "%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 // Finally set the PMKSA ID Cache in CSR
5947 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
5948 PMKIDCache,
5949 i );
5950 return 0;
5951}
5952
5953
5954static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07005955 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005956{
Jeff Johnsone7245742012-09-05 17:12:55 -07005957 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005958 // TODO: Implement this later.
5959 return 0;
5960}
5961
5962static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
5963{
Jeff Johnsone7245742012-09-05 17:12:55 -07005964 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005965 // TODO: Implement this later.
5966 return 0;
5967}
5968#endif
5969
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005970#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
5971static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
5972 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
5973{
5974 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5975 hdd_station_ctx_t *pHddStaCtx;
5976
5977 if (NULL == pAdapter)
5978 {
5979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5980 return -ENODEV;
5981 }
5982
5983 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5984
5985 // Added for debug on reception of Re-assoc Req.
5986 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5987 {
5988 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
5989 ftie->ie_len);
5990 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
5991 }
5992
5993#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
5994 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
5995 ftie->ie_len);
5996#endif
5997
5998 // Pass the received FT IEs to SME
5999 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6000 ftie->ie_len);
6001 return 0;
6002}
6003#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006004
Jeff Johnson295189b2012-06-20 16:38:30 -07006005/* cfg80211_ops */
6006static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6007{
6008 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6009 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6010 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6011 .change_station = wlan_hdd_change_station,
6012#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6013 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6014 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6015 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006016#else
6017 .start_ap = wlan_hdd_cfg80211_start_ap,
6018 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6019 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006020#endif
6021 .change_bss = wlan_hdd_cfg80211_change_bss,
6022 .add_key = wlan_hdd_cfg80211_add_key,
6023 .get_key = wlan_hdd_cfg80211_get_key,
6024 .del_key = wlan_hdd_cfg80211_del_key,
6025 .set_default_key = wlan_hdd_cfg80211_set_default_key,
6026 .set_channel = wlan_hdd_cfg80211_set_channel,
6027 .scan = wlan_hdd_cfg80211_scan,
6028 .connect = wlan_hdd_cfg80211_connect,
6029 .disconnect = wlan_hdd_cfg80211_disconnect,
6030 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6031 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6032 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6033 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6034 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6035#ifdef WLAN_FEATURE_P2P
6036 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6037 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6038 .mgmt_tx = wlan_hdd_action,
6039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6040 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6041 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6042 .set_txq_params = wlan_hdd_set_txq_params,
6043#endif
6044#endif
6045 .get_station = wlan_hdd_cfg80211_get_station,
6046 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6047 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006048 .add_station = wlan_hdd_cfg80211_add_station,
6049#ifdef FEATURE_WLAN_LFR
6050 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6051 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6052 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6053#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006054#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6055 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6056#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006057};
6058
6059#endif // CONFIG_CFG80211