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