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