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