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