blob: 2d5209d933b7bd007612b08d59ddfb962281a995 [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
Jeff Johnsone7245742012-09-05 17:12:55 -07003826allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003827 /* release the wake lock at the end of the scan*/
3828 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003829
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07003830 /* Acquire wakelock to handle the case where APP's tries to suspend
3831 * immediatly after the driver gets connect request(i.e after scan)
3832 * from supplicant, this result in app's is suspending and not able
3833 * to process the connect request to AP */
3834 hdd_allow_suspend_timeout(100);
3835
Jeff Johnson295189b2012-06-20 16:38:30 -07003836 EXIT();
3837 return 0;
3838}
3839
3840/*
3841 * FUNCTION: wlan_hdd_cfg80211_scan
3842 * this scan respond to scan trigger and update cfg80211 scan database
3843 * later, scan dump command can be used to recieve scan results
3844 */
3845int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, struct net_device *dev,
3846 struct cfg80211_scan_request *request)
3847{
3848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3849 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3850 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3851 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3852 tCsrScanRequest scanRequest;
3853 tANI_U8 *channelList = NULL, i;
3854 v_U32_t scanId = 0;
3855 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003856 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003857#ifdef WLAN_FEATURE_P2P
3858 v_U8_t* pP2pIe = NULL;
3859#endif
3860
3861 ENTER();
3862
3863 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3864 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003865
3866 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
3867 (eConnectionState_Connecting ==
3868 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
3869 {
3870 hddLog(VOS_TRACE_LEVEL_ERROR,
3871 "%s: Connection in progress: Scan request denied (EBUSY)", __func__);
3872 return -EBUSY;
3873 }
3874
Jeff Johnson295189b2012-06-20 16:38:30 -07003875#ifdef WLAN_BTAMP_FEATURE
3876 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003877 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07003878 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003879 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003880 "%s: No scanning when AMP is on", __func__);
3881 return -EOPNOTSUPP;
3882 }
3883#endif
3884 //Scan on any other interface is not supported.
3885 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
3886 {
3887 hddLog(VOS_TRACE_LEVEL_ERROR,
3888 "%s: Not scanning on device_mode = %d",
3889 __func__, pAdapter->device_mode);
3890 return -EOPNOTSUPP;
3891 }
3892
3893 if (TRUE == pScanInfo->mScanPending)
3894 {
3895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
3896 return -EBUSY;
3897 }
3898
3899 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3900 {
3901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3902 "%s:LOGP in Progress. Ignore!!!", __func__);
3903 return -EAGAIN;
3904 }
3905
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07003906 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
3907 {
3908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3909 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
3910 return -EAGAIN;
3911 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07003912 //Don't Allow Scan and return busy if Remain On
3913 //Channel and action frame is pending
3914 //Otherwise Cancel Remain On Channel and allow Scan
3915 //If no action frame pending
3916 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
3917 {
3918 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
3919 return -EBUSY;
3920 }
3921
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
3923 {
3924 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
3925 "%s: Aquire lock fail", __func__);
3926 return -EAGAIN;
3927 }
3928 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
3929 {
3930 hddLog(VOS_TRACE_LEVEL_WARN,
3931 "%s: MAX TM Level Scan not allowed", __func__);
3932 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3933 return -EBUSY;
3934 }
3935 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3936
3937 vos_mem_zero( &scanRequest, sizeof(scanRequest));
3938
3939 if (NULL != request)
3940 {
3941 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
3942 (int)request->n_ssids);
3943
3944 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
3945 * Becasue of this, driver is assuming that this is not wildcard scan and so
3946 * is not aging out the scan results.
3947 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07003948 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07003949 {
3950 request->n_ssids = 0;
3951 }
3952
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003953 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07003954 {
3955 tCsrSSIDInfo *SsidInfo;
3956 int j;
3957 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
3958 /* Allocate num_ssid tCsrSSIDInfo structure */
3959 SsidInfo = scanRequest.SSIDs.SSIDList =
3960 ( tCsrSSIDInfo *)vos_mem_malloc(
3961 request->n_ssids*sizeof(tCsrSSIDInfo));
3962
3963 if(NULL == scanRequest.SSIDs.SSIDList)
3964 {
3965 hddLog(VOS_TRACE_LEVEL_ERROR,
3966 "memory alloc failed SSIDInfo buffer");
3967 return -ENOMEM;
3968 }
3969
3970 /* copy all the ssid's and their length */
3971 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
3972 {
3973 /* get the ssid length */
3974 SsidInfo->SSID.length = request->ssids[j].ssid_len;
3975 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
3976 SsidInfo->SSID.length);
3977 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
3978 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
3979 j, SsidInfo->SSID.ssId);
3980 }
3981 /* set the scan type to active */
3982 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3983 }
3984 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
3985 {
3986 /* set the scan type to active */
3987 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3988 }
3989 else
3990 {
3991 /*Set the scan type to default type, in this case it is ACTIVE*/
3992 scanRequest.scanType = pScanInfo->scan_mode;
3993 }
3994 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
3995 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
3996 }
3997 else
3998 {
3999 /* set the scan type to active */
4000 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4001 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4002
4003 /* set min and max channel time to zero */
4004 scanRequest.minChnTime = 0;
4005 scanRequest.maxChnTime = 0;
4006 }
4007
4008 /* set BSSType to default type */
4009 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4010
4011 /*TODO: scan the requested channels only*/
4012
4013 /*Right now scanning all the channels */
4014 if( request )
4015 {
4016 if( request->n_channels )
4017 {
4018 channelList = vos_mem_malloc( request->n_channels );
4019 if( NULL == channelList )
4020 {
4021 status = -ENOMEM;
4022 goto free_mem;
4023 }
4024
4025 for( i = 0 ; i < request->n_channels ; i++ )
4026 channelList[i] = request->channels[i]->hw_value;
4027 }
4028
4029 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4030 scanRequest.ChannelInfo.ChannelList = channelList;
4031
4032 /* set requestType to full scan */
4033 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004034
4035 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4036 * search (Flush on both full scan and social scan but not on single
4037 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4038 */
4039
4040 /* Supplicant does single channel scan after 8-way handshake
4041 * and in that case driver shoudnt flush scan results. If
4042 * driver flushes the scan results here and unfortunately if
4043 * the AP doesnt respond to our probe req then association
4044 * fails which is not desired
4045 */
4046
4047 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4048 {
4049 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4050 pAdapter->sessionId );
4051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004052
4053 if( request->ie_len )
4054 {
4055 /* save this for future association (join requires this) */
4056 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4057 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4058 pScanInfo->scanAddIE.length = request->ie_len;
4059
4060 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004061 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4062 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 )
4064 {
4065 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4066 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4067 }
4068
4069 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4070 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4071
4072#ifdef WLAN_FEATURE_P2P
4073 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4074 request->ie_len);
4075 if (pP2pIe != NULL)
4076 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004077#ifdef WLAN_FEATURE_P2P_DEBUG
4078 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4079 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4080 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4081 {
4082 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4083 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4084 "Go nego completed to Connection is started");
4085 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4086 "for 8way Handshake");
4087 }
4088 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4089 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4090 {
4091 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4092 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4093 "Disconnected state to Connection is started");
4094 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4095 "for 4way Handshake");
4096 }
4097#endif
4098
Jeff Johnsone7245742012-09-05 17:12:55 -07004099 /* no_cck will be set during p2p find to disable 11b rates */
4100 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004101 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004102 hddLog(VOS_TRACE_LEVEL_INFO,
4103 "%s: This is a P2P Search", __func__);
4104 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004105
Jeff Johnsone7245742012-09-05 17:12:55 -07004106 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4107 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004108 /* set requestType to P2P Discovery */
4109 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004110 }
4111
4112 /*
4113 Skip Dfs Channel in case of P2P Search
4114 if it is set in ini file
4115 */
4116 if(cfg_param->skipDfsChnlInP2pSearch)
4117 {
4118 scanRequest.skipDfsChnlInP2pSearch = 1;
4119 }
4120 else
4121 {
4122 scanRequest.skipDfsChnlInP2pSearch = 0;
4123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004124
Jeff Johnson295189b2012-06-20 16:38:30 -07004125 }
4126 }
4127#endif
4128 }
4129 }
4130
4131 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4132
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004133 /* acquire the wakelock to avoid the apps suspend during the scan. To
4134 * address the following issues.
4135 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4136 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4137 * for long time, this result in apps running at full power for long time.
4138 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4139 * be stuck in full power because of resume BMPS
4140 */
4141 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004142
4143 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004144 pAdapter->sessionId, &scanRequest, &scanId,
4145 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004146
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 if (eHAL_STATUS_SUCCESS != status)
4148 {
4149 hddLog(VOS_TRACE_LEVEL_ERROR,
4150 "%s: sme_ScanRequest returned error %d", __func__, status);
4151 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004152 if(eHAL_STATUS_RESOURCES == status)
4153 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004154 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 -07004155 status = -EBUSY;
4156 } else {
4157 status = -EIO;
4158 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004159 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 goto free_mem;
4161 }
4162
4163 pScanInfo->mScanPending = TRUE;
4164 pAdapter->request = request;
4165 pScanInfo->scanId = scanId;
4166
4167 complete(&pScanInfo->scan_req_completion_event);
4168
4169free_mem:
4170 if( scanRequest.SSIDs.SSIDList )
4171 {
4172 vos_mem_free(scanRequest.SSIDs.SSIDList);
4173 }
4174
4175 if( channelList )
4176 vos_mem_free( channelList );
4177
4178 EXIT();
4179
4180 return status;
4181}
4182
4183/*
4184 * FUNCTION: wlan_hdd_cfg80211_connect_start
4185 * This function is used to start the association process
4186 */
4187int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004188 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004189{
4190 int status = 0;
4191 hdd_wext_state_t *pWextState;
4192 v_U32_t roamId;
4193 tCsrRoamProfile *pRoamProfile;
4194 eMib_dot11DesiredBssType connectedBssType;
4195 eCsrAuthType RSNAuthType;
4196
4197 ENTER();
4198
4199 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4200
4201 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4202 {
4203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4204 return -EINVAL;
4205 }
4206
4207 pRoamProfile = &pWextState->roamProfile;
4208
4209 if (pRoamProfile)
4210 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004211 int ret = 0;
4212 hdd_station_ctx_t *pHddStaCtx;
4213 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4214 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4215
4216 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4217 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4218 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 {
4220 /* Issue disconnect to CSR */
4221 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4222 if( eHAL_STATUS_SUCCESS ==
4223 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4224 pAdapter->sessionId,
4225 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4226 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004227 ret = wait_for_completion_interruptible_timeout(
4228 &pAdapter->disconnect_comp_var,
4229 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4230 if (0 == ret)
4231 {
4232 VOS_ASSERT(0);
4233 }
4234 }
4235 }
4236 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4237 {
4238 ret = wait_for_completion_interruptible_timeout(
4239 &pAdapter->disconnect_comp_var,
4240 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4241 if (0 == ret)
4242 {
4243 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004244 }
4245 }
4246
4247 if (HDD_WMM_USER_MODE_NO_QOS ==
4248 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4249 {
4250 /*QoS not enabled in cfg file*/
4251 pRoamProfile->uapsd_mask = 0;
4252 }
4253 else
4254 {
4255 /*QoS enabled, update uapsd mask from cfg file*/
4256 pRoamProfile->uapsd_mask =
4257 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4258 }
4259
4260 pRoamProfile->SSIDs.numOfSSIDs = 1;
4261 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4262 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4263 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4264 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4265 ssid, ssid_len);
4266
4267 if (bssid)
4268 {
4269 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4270 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4271 WNI_CFG_BSSID_LEN);
4272 /* Save BSSID in seperate variable as well, as RoamProfile
4273 BSSID is getting zeroed out in the association process. And in
4274 case of join failure we should send valid BSSID to supplicant
4275 */
4276 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4277 WNI_CFG_BSSID_LEN);
4278 }
4279
4280 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4281 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4282 {
4283 /*set gen ie*/
4284 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4285 /*set auth*/
4286 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4287 }
4288 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4289 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4290 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4291 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4292 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4293 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4294 )
4295 {
4296 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4297 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4298 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4299 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4300 eCSR_AUTH_TYPE_AUTOSWITCH;
4301 pWextState->roamProfile.AuthType.authType[0] =
4302 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4303 }
4304#ifdef FEATURE_WLAN_WAPI
4305 if (pAdapter->wapi_info.nWapiMode)
4306 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004307 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004308 switch (pAdapter->wapi_info.wapiAuthMode)
4309 {
4310 case WAPI_AUTH_MODE_PSK:
4311 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004312 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004313 pAdapter->wapi_info.wapiAuthMode);
4314 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4315 break;
4316 }
4317 case WAPI_AUTH_MODE_CERT:
4318 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004319 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004320 pAdapter->wapi_info.wapiAuthMode);
4321 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4322 break;
4323 }
4324 } // End of switch
4325 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4326 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4327 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004328 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004329 pRoamProfile->AuthType.numEntries = 1;
4330 pRoamProfile->EncryptionType.numEntries = 1;
4331 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4332 pRoamProfile->mcEncryptionType.numEntries = 1;
4333 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4334 }
4335 }
4336#endif /* FEATURE_WLAN_WAPI */
4337 pRoamProfile->csrPersona = pAdapter->device_mode;
4338
Jeff Johnson32d95a32012-09-10 13:15:23 -07004339 if( operatingChannel )
4340 {
4341 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4342 pRoamProfile->ChannelInfo.numOfChannels = 1;
4343 }
4344
Jeff Johnson295189b2012-06-20 16:38:30 -07004345 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4346 pAdapter->sessionId, pRoamProfile, &roamId);
4347
Jeff Johnson32d95a32012-09-10 13:15:23 -07004348 pRoamProfile->ChannelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004349 pRoamProfile->ChannelInfo.numOfChannels = 0;
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304350
4351 if( (eHAL_STATUS_SUCCESS == status) &&
4352 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4353
4354 {
4355 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4356 eConnectionState_Connecting);
4357 }
4358
4359 if( status != eHAL_STATUS_SUCCESS )
4360 {
4361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect failed with "
4362 "status %d", __func__, status);
4363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004364 }
4365 else
4366 {
4367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4368 return -EINVAL;
4369 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004370 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004371 return status;
4372}
4373
4374/*
4375 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4376 * This function is used to set the authentication type (OPEN/SHARED).
4377 *
4378 */
4379static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4380 enum nl80211_auth_type auth_type)
4381{
4382 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4383 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4384
4385 ENTER();
4386
4387 /*set authentication type*/
4388 switch (auth_type)
4389 {
4390 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4391 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004392#ifdef WLAN_FEATURE_VOWIFI_11R
4393 case NL80211_AUTHTYPE_FT:
4394#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004395 hddLog(VOS_TRACE_LEVEL_INFO,
4396 "%s: set authentication type to OPEN", __func__);
4397 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4398 break;
4399
4400 case NL80211_AUTHTYPE_SHARED_KEY:
4401 hddLog(VOS_TRACE_LEVEL_INFO,
4402 "%s: set authentication type to SHARED", __func__);
4403 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4404 break;
4405#ifdef FEATURE_WLAN_CCX
4406 case NL80211_AUTHTYPE_NETWORK_EAP:
4407 hddLog(VOS_TRACE_LEVEL_INFO,
4408 "%s: set authentication type to CCKM WPA", __func__);
4409 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4410 break;
4411#endif
4412
4413
4414 default:
4415 hddLog(VOS_TRACE_LEVEL_ERROR,
4416 "%s: Unsupported authentication type %d", __func__,
4417 auth_type);
4418 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4419 return -EINVAL;
4420 }
4421
4422 pWextState->roamProfile.AuthType.authType[0] =
4423 pHddStaCtx->conn_info.authType;
4424 return 0;
4425}
4426
4427/*
4428 * FUNCTION: wlan_hdd_set_akm_suite
4429 * This function is used to set the key mgmt type(PSK/8021x).
4430 *
4431 */
4432static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4433 u32 key_mgmt
4434 )
4435{
4436 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4437 ENTER();
4438
4439 /*set key mgmt type*/
4440 switch(key_mgmt)
4441 {
4442 case WLAN_AKM_SUITE_PSK:
4443 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4444 __func__);
4445 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4446 break;
4447
4448 case WLAN_AKM_SUITE_8021X:
4449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4450 __func__);
4451 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4452 break;
4453#ifdef FEATURE_WLAN_CCX
4454#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4455#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4456 case WLAN_AKM_SUITE_CCKM:
4457 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4458 __func__);
4459 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4460 break;
4461#endif
4462
4463 default:
4464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4465 __func__, key_mgmt);
4466 return -EINVAL;
4467
4468 }
4469 return 0;
4470}
4471
4472/*
4473 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4474 * This function is used to set the encryption type
4475 * (NONE/WEP40/WEP104/TKIP/CCMP).
4476 */
4477static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4478 u32 cipher,
4479 bool ucast
4480 )
4481{
4482 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4483 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4484 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4485
4486 ENTER();
4487
4488 if (!cipher)
4489 {
4490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4491 __func__, cipher);
4492 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4493 }
4494 else
4495 {
4496
4497 /*set encryption method*/
4498 switch (cipher)
4499 {
4500 case IW_AUTH_CIPHER_NONE:
4501 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4502 break;
4503
4504 case WLAN_CIPHER_SUITE_WEP40:
4505 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4506 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4507 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4508 else
4509 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4510 break;
4511
4512 case WLAN_CIPHER_SUITE_WEP104:
4513 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4514 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4515 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4516 else
4517 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4518 break;
4519
4520 case WLAN_CIPHER_SUITE_TKIP:
4521 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4522 break;
4523
4524 case WLAN_CIPHER_SUITE_CCMP:
4525 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4526 break;
4527#ifdef FEATURE_WLAN_WAPI
4528 case WLAN_CIPHER_SUITE_SMS4:
4529 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4530 break;
4531#endif
4532
4533#ifdef FEATURE_WLAN_CCX
4534 case WLAN_CIPHER_SUITE_KRK:
4535 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4536 break;
4537#endif
4538 default:
4539 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4540 __func__, cipher);
4541 return -EOPNOTSUPP;
4542 }
4543 }
4544
4545 if (ucast)
4546 {
4547 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4548 __func__, encryptionType);
4549 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4550 pWextState->roamProfile.EncryptionType.numEntries = 1;
4551 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4552 encryptionType;
4553 }
4554 else
4555 {
4556 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4557 __func__, encryptionType);
4558 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4559 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4560 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4561 }
4562
4563 return 0;
4564}
4565
4566
4567/*
4568 * FUNCTION: wlan_hdd_cfg80211_set_ie
4569 * This function is used to parse WPA/RSN IE's.
4570 */
4571int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4572 u8 *ie,
4573 size_t ie_len
4574 )
4575{
4576 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4577 u8 *genie = ie;
4578 v_U16_t remLen = ie_len;
4579#ifdef FEATURE_WLAN_WAPI
4580 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4581 u16 *tmp;
4582 v_U16_t akmsuiteCount;
4583 int *akmlist;
4584#endif
4585 ENTER();
4586
4587 /* clear previous assocAddIE */
4588 pWextState->assocAddIE.length = 0;
4589 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4590
4591 while (remLen >= 2)
4592 {
4593 v_U16_t eLen = 0;
4594 v_U8_t elementId;
4595 elementId = *genie++;
4596 eLen = *genie++;
4597 remLen -= 2;
4598
4599 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4600 __func__, elementId, eLen);
4601
4602 switch ( elementId )
4603 {
4604 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004605 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 -07004606 {
4607 hddLog(VOS_TRACE_LEVEL_ERROR,
4608 "%s: Invalid WPA IE", __func__);
4609 return -EINVAL;
4610 }
4611 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4612 {
4613 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4614 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4615 __func__, eLen + 2);
4616
4617 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4618 {
4619 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE. "
4620 "Need bigger buffer space\n");
4621 VOS_ASSERT(0);
4622 return -ENOMEM;
4623 }
4624 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4625 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4626 pWextState->assocAddIE.length += eLen + 2;
4627
4628 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4629 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4630 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4631 }
4632 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4633 {
4634 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4635 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4636 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4637 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4638 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4639 }
4640#ifdef WLAN_FEATURE_P2P
4641 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4642 P2P_OUI_TYPE_SIZE))
4643 /*Consider P2P IE, only for P2P Client */
4644 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4645 {
4646 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4647 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4648 __func__, eLen + 2);
4649
4650 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4651 {
4652 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4653 "Need bigger buffer space\n");
4654 VOS_ASSERT(0);
4655 return -ENOMEM;
4656 }
4657 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4658 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4659 pWextState->assocAddIE.length += eLen + 2;
4660
4661 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4662 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4663 }
4664#endif
4665#ifdef WLAN_FEATURE_WFD
4666 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4667 WFD_OUI_TYPE_SIZE))
4668 /*Consider WFD IE, only for P2P Client */
4669 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4670 {
4671 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4672 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4673 __func__, eLen + 2);
4674
4675 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4676 {
4677 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4678 "Need bigger buffer space\n");
4679 VOS_ASSERT(0);
4680 return -ENOMEM;
4681 }
4682 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4683 // WPS IE + P2P IE + WFD IE
4684 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4685 pWextState->assocAddIE.length += eLen + 2;
4686
4687 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4688 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4689 }
4690#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004691 /* Appending HS 2.0 Indication Element in Assiciation Request */
4692 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004693 HS20_OUI_TYPE_SIZE)) )
4694 {
4695 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4696 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4697 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004698
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004699 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4700 {
4701 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4702 "Need bigger buffer space\n");
4703 VOS_ASSERT(0);
4704 return -ENOMEM;
4705 }
4706 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4707 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004708
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004709 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4710 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4711 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004712
Jeff Johnson295189b2012-06-20 16:38:30 -07004713 break;
4714 case DOT11F_EID_RSN:
4715 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4716 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4717 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4718 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4719 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4720 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004721 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4722 case DOT11F_EID_EXTCAP:
4723 {
4724 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4725 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
4726 __func__, eLen + 2);
4727
4728 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4729 {
4730 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4731 "Need bigger buffer space\n");
4732 VOS_ASSERT(0);
4733 return -ENOMEM;
4734 }
4735 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4736 pWextState->assocAddIE.length += eLen + 2;
4737
4738 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4739 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4740 break;
4741 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004742#ifdef FEATURE_WLAN_WAPI
4743 case WLAN_EID_WAPI:
4744 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
4745 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
4746 pAdapter->wapi_info.nWapiMode);
4747 tmp = (u16 *)ie;
4748 tmp = tmp + 2; // Skip element Id and Len, Version
4749 akmsuiteCount = WPA_GET_LE16(tmp);
4750 tmp = tmp + 1;
4751 akmlist = (int *)(tmp);
4752 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
4753 {
4754 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
4755 }
4756 else
4757 {
4758 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
4759 VOS_ASSERT(0);
4760 return -EINVAL;
4761 }
4762
4763 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
4764 {
4765 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004766 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004767 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
4768 }
4769 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
4770 {
4771 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004772 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004773 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
4774 }
4775 break;
4776#endif
4777 default:
4778 hddLog (VOS_TRACE_LEVEL_ERROR,
4779 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004780 /* when Unknown IE is received we should break and continue
4781 * to the next IE in the buffer instead we were returning
4782 * so changing this to break */
4783 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07004784 }
4785 genie += eLen;
4786 remLen -= eLen;
4787 }
4788 EXIT();
4789 return 0;
4790}
4791
4792/*
4793 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4794 * This function is used to initialize the security
4795 * parameters during connect operation.
4796 */
4797int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
4798 struct cfg80211_connect_params *req
4799 )
4800{
4801 int status = 0;
4802 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4803 ENTER();
4804
4805 /*set wpa version*/
4806 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4807
4808 if (req->crypto.wpa_versions)
4809 {
4810 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
4811 && ( (req->ie_len)
4812 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
4813 // Make sure that it is including a WPA IE.
4814 /* Currently NL is putting WPA version 1 even for open,
4815 * since p2p ie is also put in same buffer.
4816 * */
4817 {
4818 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
4819 }
4820 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
4821 {
4822 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
4823 }
4824 }
4825
4826 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
4827 pWextState->wpaVersion);
4828
4829 /*set authentication type*/
4830 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
4831
4832 if (0 > status)
4833 {
4834 hddLog(VOS_TRACE_LEVEL_ERROR,
4835 "%s: failed to set authentication type ", __func__);
4836 return status;
4837 }
4838
4839 /*set key mgmt type*/
4840 if (req->crypto.n_akm_suites)
4841 {
4842 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
4843 if (0 > status)
4844 {
4845 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
4846 __func__);
4847 return status;
4848 }
4849 }
4850
4851 /*set pairwise cipher type*/
4852 if (req->crypto.n_ciphers_pairwise)
4853 {
4854 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
4855 req->crypto.ciphers_pairwise[0], true);
4856 if (0 > status)
4857 {
4858 hddLog(VOS_TRACE_LEVEL_ERROR,
4859 "%s: failed to set unicast cipher type", __func__);
4860 return status;
4861 }
4862 }
4863 else
4864 {
4865 /*Reset previous cipher suite to none*/
4866 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
4867 if (0 > status)
4868 {
4869 hddLog(VOS_TRACE_LEVEL_ERROR,
4870 "%s: failed to set unicast cipher type", __func__);
4871 return status;
4872 }
4873 }
4874
4875 /*set group cipher type*/
4876 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
4877 false);
4878
4879 if (0 > status)
4880 {
4881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
4882 __func__);
4883 return status;
4884 }
4885
4886 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
4887 if (req->ie_len)
4888 {
4889 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
4890 if ( 0 > status)
4891 {
4892 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
4893 __func__);
4894 return status;
4895 }
4896 }
4897
4898 /*incase of WEP set default key information*/
4899 if (req->key && req->key_len)
4900 {
4901 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
4902 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
4903 )
4904 {
4905 if ( IW_AUTH_KEY_MGMT_802_1X
4906 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
4907 {
4908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
4909 __func__);
4910 return -EOPNOTSUPP;
4911 }
4912 else
4913 {
4914 u8 key_len = req->key_len;
4915 u8 key_idx = req->key_idx;
4916
4917 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
4918 && (CSR_MAX_NUM_KEY > key_idx)
4919 )
4920 {
4921 hddLog(VOS_TRACE_LEVEL_INFO,
4922 "%s: setting default wep key, key_idx = %hu key_len %hu",
4923 __func__, key_idx, key_len);
4924 vos_mem_copy(
4925 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
4926 req->key, key_len);
4927 pWextState->roamProfile.Keys.KeyLength[key_idx] =
4928 (u8)key_len;
4929 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
4930 }
4931 }
4932 }
4933 }
4934
4935 return status;
4936}
4937
4938/*
4939 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4940 * This function is used to initialize the security
4941 * parameters during connect operation.
4942 */
4943static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
4944 struct net_device *ndev,
4945 struct cfg80211_connect_params *req
4946 )
4947{
4948 int status = 0;
4949 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4950 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
4951 hdd_context_t *pHddCtx = NULL;
4952
4953 ENTER();
4954
4955 hddLog(VOS_TRACE_LEVEL_INFO,
4956 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
4957
4958 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
4959 {
4960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4961 "%s:LOGP in Progress. Ignore!!!", __func__);
4962 return -EAGAIN;
4963 }
4964
4965#ifdef WLAN_BTAMP_FEATURE
4966 //Infra connect not supported when AMP traffic is on.
4967 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
4968 {
4969 hddLog(VOS_TRACE_LEVEL_ERROR,
4970 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004971 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07004972 }
4973#endif
4974 /*initialise security parameters*/
4975 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
4976
4977 if ( 0 > status)
4978 {
4979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
4980 __func__);
4981 return status;
4982 }
4983
4984 //If Device Mode is Station Concurrent Sessions Exit BMps
4985 //P2P Mode will be taken care in Open/close adaptor
4986 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4987 (vos_concurrent_sessions_running()))
4988 {
4989 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
4990
4991 if (NULL != pVosContext)
4992 {
4993 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
4994 if(NULL != pHddCtx)
4995 {
4996 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
4997 }
4998 }
4999 }
5000
Mohit Khanna765234a2012-09-11 15:08:35 -07005001 if ( req->channel )
5002 {
5003 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5004 req->ssid_len, req->bssid,
5005 req->channel->hw_value);
5006 }
5007 else
5008 {
5009 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5010 req->ssid_len, req->bssid,
5011 0);
5012 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005013
5014 if (0 > status)
5015 {
5016 //ReEnable BMPS if disabled
5017 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5018 (NULL != pHddCtx))
5019 {
5020 //ReEnable Bmps and Imps back
5021 hdd_enable_bmps_imps(pHddCtx);
5022 }
5023
5024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5025 return status;
5026 }
5027 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5028 EXIT();
5029 return status;
5030}
5031
5032
5033/*
5034 * FUNCTION: wlan_hdd_cfg80211_disconnect
5035 * This function is used to issue a disconnect request to SME
5036 */
5037static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5038 struct net_device *dev,
5039 u16 reason
5040 )
5041{
5042 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5043 tCsrRoamProfile *pRoamProfile =
5044 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5045 int status = 0;
5046 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5047
5048 ENTER();
5049
5050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5051 __func__,pAdapter->device_mode);
5052
5053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5054 __func__, reason);
5055
5056 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5057 {
5058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5059 "%s:LOGP in Progress. Ignore!!!",__func__);
5060 return -EAGAIN;
5061 }
5062 if (NULL != pRoamProfile)
5063 {
5064 /*issue disconnect request to SME, if station is in connected state*/
5065 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5066 {
5067 eCsrRoamDisconnectReason reasonCode =
5068 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5069 switch(reason)
5070 {
5071 case WLAN_REASON_MIC_FAILURE:
5072 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5073 break;
5074
5075 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5076 case WLAN_REASON_DISASSOC_AP_BUSY:
5077 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5078 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5079 break;
5080
5081 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5082 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5083 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5084 break;
5085
5086 case WLAN_REASON_DEAUTH_LEAVING:
5087 default:
5088 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5089 break;
5090 }
5091 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5092 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5093 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5094
5095 /*issue disconnect*/
5096 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5097 pAdapter->sessionId, reasonCode);
5098
5099 if ( 0 != status)
5100 {
5101 hddLog(VOS_TRACE_LEVEL_ERROR,
5102 "%s csrRoamDisconnect failure, returned %d \n",
5103 __func__, (int)status );
5104 return -EINVAL;
5105 }
5106
5107 wait_for_completion_interruptible_timeout(
5108 &pAdapter->disconnect_comp_var,
5109 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5110
5111
5112 /*stop tx queues*/
5113 netif_tx_disable(dev);
5114 netif_carrier_off(dev);
5115 }
5116 }
5117 else
5118 {
5119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5120 }
5121
5122 return status;
5123}
5124
5125/*
5126 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5127 * This function is used to initialize the security
5128 * settings in IBSS mode.
5129 */
5130static int wlan_hdd_cfg80211_set_privacy_ibss(
5131 hdd_adapter_t *pAdapter,
5132 struct cfg80211_ibss_params *params
5133 )
5134{
5135 int status = 0;
5136 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5137 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5138 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5139
5140 ENTER();
5141
5142 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5143
5144 if (params->ie_len && ( NULL != params->ie) )
5145 {
5146 if (WLAN_EID_RSN == params->ie[0])
5147 {
5148 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5149 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5150 }
5151 else
5152 {
5153 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5154 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5155 }
5156 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5157
5158 if (0 > status)
5159 {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5161 __func__);
5162 return status;
5163 }
5164 }
5165
5166 pWextState->roamProfile.AuthType.authType[0] =
5167 pHddStaCtx->conn_info.authType =
5168 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5169
5170 if (params->privacy)
5171 {
5172 /* Security enabled IBSS, At this time there is no information available
5173 * about the security paramters, so initialise the encryption type to
5174 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5175 * The correct security parameters will be updated later in
5176 * wlan_hdd_cfg80211_add_key */
5177 /* Hal expects encryption type to be set inorder
5178 *enable privacy bit in beacons */
5179
5180 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5181 }
5182
5183 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5184 pWextState->roamProfile.EncryptionType.numEntries = 1;
5185 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5186
5187 return status;
5188}
5189
5190/*
5191 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5192 * This function is used to create/join an IBSS
5193 */
5194static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5195 struct net_device *dev,
5196 struct cfg80211_ibss_params *params
5197 )
5198{
5199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5200 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5201 tCsrRoamProfile *pRoamProfile;
5202 int status;
5203 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5204
5205 ENTER();
5206
5207 hddLog(VOS_TRACE_LEVEL_INFO,
5208 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5209
5210 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5211 {
5212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5213 "%s:LOGP in Progress. Ignore!!!", __func__);
5214 return -EAGAIN;
5215 }
5216
5217 if (NULL == pWextState)
5218 {
5219 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5220 __func__);
5221 return -EIO;
5222 }
5223
5224 pRoamProfile = &pWextState->roamProfile;
5225
5226 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5227 {
5228 hddLog (VOS_TRACE_LEVEL_ERROR,
5229 "%s Interface type is not set to IBSS \n", __func__);
5230 return -EINVAL;
5231 }
5232
5233 /* Set Channel */
5234 if (NULL != params->channel)
5235 {
5236 u8 channelNum;
5237 if (IEEE80211_BAND_5GHZ == params->channel->band)
5238 {
5239 hddLog(VOS_TRACE_LEVEL_ERROR,
5240 "%s: IBSS join is called with unsupported band %d",
5241 __func__, params->channel->band);
5242 return -EOPNOTSUPP;
5243 }
5244
5245 /* Get channel number */
5246 channelNum =
5247 ieee80211_frequency_to_channel(params->channel->center_freq);
5248
5249 /*TODO: use macro*/
5250 if (14 >= channelNum)
5251 {
5252 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5253 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5254 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5255 int indx;
5256
5257 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5258 validChan, &numChans))
5259 {
5260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5261 __func__);
5262 return -EOPNOTSUPP;
5263 }
5264
5265 for (indx = 0; indx < numChans; indx++)
5266 {
5267 if (channelNum == validChan[indx])
5268 {
5269 break;
5270 }
5271 }
5272 if (indx >= numChans)
5273 {
5274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5275 __func__, channelNum);
5276 return -EINVAL;
5277 }
5278 /* Set the Operational Channel */
5279 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5280 channelNum);
5281 pRoamProfile->ChannelInfo.numOfChannels = 1;
5282 pHddStaCtx->conn_info.operationChannel = channelNum;
5283 pRoamProfile->ChannelInfo.ChannelList =
5284 &pHddStaCtx->conn_info.operationChannel;
5285 }
5286 else
5287 {
5288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5289 __func__, channelNum);
5290 return -EINVAL;
5291 }
5292 }
5293
5294 /* Initialize security parameters */
5295 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5296 if (status < 0)
5297 {
5298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5299 __func__);
5300 return status;
5301 }
5302
5303 /* Issue connect start */
5304 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005305 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005306
5307 if (0 > status)
5308 {
5309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5310 return status;
5311 }
5312
5313 return 0;
5314}
5315
5316/*
5317 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5318 * This function is used to leave an IBSS
5319 */
5320static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5321 struct net_device *dev
5322 )
5323{
5324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5325 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5326 tCsrRoamProfile *pRoamProfile;
5327
5328 ENTER();
5329
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005330 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5331 {
5332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5333 "%s:LOGP in Progress. Ignore!!!", __func__);
5334 return -EAGAIN;
5335 }
5336
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5338 if (NULL == pWextState)
5339 {
5340 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5341 __func__);
5342 return -EIO;
5343 }
5344
5345 pRoamProfile = &pWextState->roamProfile;
5346
5347 /* Issue disconnect only if interface type is set to IBSS */
5348 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5349 {
5350 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5351 __func__);
5352 return -EINVAL;
5353 }
5354
5355 /* Issue Disconnect request */
5356 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5357 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5358 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5359
5360 return 0;
5361}
5362
5363/*
5364 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5365 * This function is used to set the phy parameters
5366 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5367 */
5368static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5369 u32 changed)
5370{
5371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5372 tHalHandle hHal = pHddCtx->hHal;
5373
5374 ENTER();
5375
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005376 if ( pHddCtx->isLogpInProgress )
5377 {
5378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5379 "%s:LOGP in Progress. Ignore!!!", __func__);
5380 return -EAGAIN;
5381 }
5382
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5384 {
5385 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5386 WNI_CFG_RTS_THRESHOLD_STAMAX :
5387 wiphy->rts_threshold;
5388
5389 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5390 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5391 {
5392 hddLog(VOS_TRACE_LEVEL_ERROR,
5393 "%s: Invalid RTS Threshold value %hu",
5394 __func__, rts_threshold);
5395 return -EINVAL;
5396 }
5397
5398 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5399 rts_threshold, ccmCfgSetCallback,
5400 eANI_BOOLEAN_TRUE))
5401 {
5402 hddLog(VOS_TRACE_LEVEL_ERROR,
5403 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5404 __func__, rts_threshold);
5405 return -EIO;
5406 }
5407
5408 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5409 rts_threshold);
5410 }
5411
5412 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5413 {
5414 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5415 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5416 wiphy->frag_threshold;
5417
5418 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5419 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5420 {
5421 hddLog(VOS_TRACE_LEVEL_ERROR,
5422 "%s: Invalid frag_threshold value %hu", __func__,
5423 frag_threshold);
5424 return -EINVAL;
5425 }
5426
5427 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5428 frag_threshold, ccmCfgSetCallback,
5429 eANI_BOOLEAN_TRUE))
5430 {
5431 hddLog(VOS_TRACE_LEVEL_ERROR,
5432 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5433 __func__, frag_threshold);
5434 return -EIO;
5435 }
5436
5437 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5438 frag_threshold);
5439 }
5440
5441 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5442 || (changed & WIPHY_PARAM_RETRY_LONG))
5443 {
5444 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5445 wiphy->retry_short :
5446 wiphy->retry_long;
5447
5448 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5449 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5450 {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5452 __func__, retry_value);
5453 return -EINVAL;
5454 }
5455
5456 if (changed & WIPHY_PARAM_RETRY_SHORT)
5457 {
5458 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5459 retry_value, ccmCfgSetCallback,
5460 eANI_BOOLEAN_TRUE))
5461 {
5462 hddLog(VOS_TRACE_LEVEL_ERROR,
5463 "%s: ccmCfgSetInt failed for long retry count %hu",
5464 __func__, retry_value);
5465 return -EIO;
5466 }
5467 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5468 __func__, retry_value);
5469 }
5470 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5471 {
5472 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5473 retry_value, ccmCfgSetCallback,
5474 eANI_BOOLEAN_TRUE))
5475 {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 "%s: ccmCfgSetInt failed for short retry count %hu",
5478 __func__, retry_value);
5479 return -EIO;
5480 }
5481 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5482 __func__, retry_value);
5483 }
5484 }
5485
5486 return 0;
5487}
5488
5489/*
5490 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5491 * This function is used to set the txpower
5492 */
5493static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5494#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5495 enum tx_power_setting type,
5496#else
5497 enum nl80211_tx_power_setting type,
5498#endif
5499 int dbm)
5500{
5501 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5502 tHalHandle hHal = pHddCtx->hHal;
5503 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5504 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5505
5506 ENTER();
5507
5508 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5509 dbm, ccmCfgSetCallback,
5510 eANI_BOOLEAN_TRUE))
5511 {
5512 hddLog(VOS_TRACE_LEVEL_ERROR,
5513 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5514 return -EIO;
5515 }
5516
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005517 if ( pHddCtx->isLogpInProgress )
5518 {
5519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5520 "%s:LOGP in Progress. Ignore!!!", __func__);
5521 return -EAGAIN;
5522 }
5523
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5525 dbm);
5526
5527 switch(type)
5528 {
5529 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5530 /* Fall through */
5531 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5532 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5533 {
5534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5535 __func__);
5536 return -EIO;
5537 }
5538 break;
5539 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5541 __func__);
5542 return -EOPNOTSUPP;
5543 break;
5544 default:
5545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5546 __func__, type);
5547 return -EIO;
5548 }
5549
5550 return 0;
5551}
5552
5553/*
5554 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5555 * This function is used to read the txpower
5556 */
5557static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5558{
5559
5560 hdd_adapter_t *pAdapter;
5561 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5562
Jeff Johnsone7245742012-09-05 17:12:55 -07005563 ENTER();
5564
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 if (NULL == pHddCtx)
5566 {
5567 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5568 *dbm = 0;
5569 return -ENOENT;
5570 }
5571
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005572 if ( pHddCtx->isLogpInProgress )
5573 {
5574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5575 "%s:LOGP in Progress. Ignore!!!", __func__);
5576 return -EAGAIN;
5577 }
5578
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5580 if (NULL == pAdapter)
5581 {
5582 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5583 return -ENOENT;
5584 }
5585
5586 wlan_hdd_get_classAstats(pAdapter);
5587 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5588
Jeff Johnsone7245742012-09-05 17:12:55 -07005589 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 return 0;
5591}
5592
5593static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5594 u8* mac, struct station_info *sinfo)
5595{
5596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5597 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5598 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5599 tANI_U8 rate_flags;
5600
5601 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5602 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5603 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5604
5605 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5606 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5607 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5608 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5609 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5610 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5611 tANI_U16 maxRate = 0;
5612 tANI_U16 myRate;
5613 tANI_U16 currentRate = 0;
5614 tANI_U8 maxSpeedMCS = 0;
5615 tANI_U8 maxMCSIdx = 0;
5616 tANI_U8 rateFlag = 1;
5617 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005618 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005619
Jeff Johnsone7245742012-09-05 17:12:55 -07005620 ENTER();
5621
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5623 (0 == ssidlen))
5624 {
5625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5626 " Invalid ssidlen, %d", __func__, ssidlen);
5627 /*To keep GUI happy*/
5628 return 0;
5629 }
5630
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005631 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5632 {
5633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5634 "%s:LOGP in Progress. Ignore!!!", __func__);
5635 return -EAGAIN;
5636 }
5637
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5639 sinfo->filled |= STATION_INFO_SIGNAL;
5640
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005641 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5643
5644 //convert to the UI units of 100kbps
5645 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5646
5647#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005648 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 -07005649 sinfo->signal,
5650 pCfg->reportMaxLinkSpeed,
5651 myRate,
5652 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005653 (int) pCfg->linkSpeedRssiMid,
5654 (int) pCfg->linkSpeedRssiLow,
5655 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005656#endif //LINKSPEED_DEBUG_ENABLED
5657
5658 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5659 {
5660 // we do not want to necessarily report the current speed
5661 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5662 {
5663 // report the max possible speed
5664 rssidx = 0;
5665 }
5666 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5667 {
5668 // report the max possible speed with RSSI scaling
5669 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5670 {
5671 // report the max possible speed
5672 rssidx = 0;
5673 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005674 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005675 {
5676 // report middle speed
5677 rssidx = 1;
5678 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005679 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5680 {
5681 // report middle speed
5682 rssidx = 2;
5683 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 else
5685 {
5686 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005687 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 }
5689 }
5690 else
5691 {
5692 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5693 hddLog(VOS_TRACE_LEVEL_ERROR,
5694 "%s: Invalid value for reportMaxLinkSpeed: %u",
5695 __func__, pCfg->reportMaxLinkSpeed);
5696 rssidx = 0;
5697 }
5698
5699 maxRate = 0;
5700
5701 /* Get Basic Rate Set */
5702 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5703 for (i = 0; i < ORLeng; i++)
5704 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005705 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 {
5707 /* Validate Rate Set */
5708 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5709 {
5710 currentRate = supported_data_rate[j].supported_rate[rssidx];
5711 break;
5712 }
5713 }
5714 /* Update MAX rate */
5715 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5716 }
5717
5718 /* Get Extended Rate Set */
5719 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5720 for (i = 0; i < ERLeng; i++)
5721 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005722 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 {
5724 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
5725 {
5726 currentRate = supported_data_rate[j].supported_rate[rssidx];
5727 break;
5728 }
5729 }
5730 /* Update MAX rate */
5731 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5732 }
5733
5734 /* Get MCS Rate Set -- but only if we are connected at MCS
5735 rates or if we are always reporting max speed or if we have
5736 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005737 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 {
5739 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
5740 rateFlag = 0;
5741 if (rate_flags & eHAL_TX_RATE_HT40)
5742 {
5743 rateFlag |= 1;
5744 }
5745 if (rate_flags & eHAL_TX_RATE_SGI)
5746 {
5747 rateFlag |= 2;
5748 }
5749
5750 for (i = 0; i < MCSLeng; i++)
5751 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005752 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
5753 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 {
5755 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
5756 {
5757 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
5758 break;
5759 }
5760 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005761 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 {
5763 maxRate = currentRate;
5764 maxSpeedMCS = 1;
5765 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
5766 }
5767 }
5768 }
5769
5770 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005771 if (((maxRate < myRate) && (0 == rssidx)) ||
5772 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 {
5774 maxRate = myRate;
5775 if (rate_flags & eHAL_TX_RATE_LEGACY)
5776 {
5777 maxSpeedMCS = 0;
5778 }
5779 else
5780 {
5781 maxSpeedMCS = 1;
5782 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5783 }
5784 }
5785
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005786 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 {
5788 sinfo->txrate.legacy = maxRate;
5789#ifdef LINKSPEED_DEBUG_ENABLED
5790 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
5791#endif //LINKSPEED_DEBUG_ENABLED
5792 }
5793 else
5794 {
5795 sinfo->txrate.mcs = maxMCSIdx;
5796 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5797 if (rate_flags & eHAL_TX_RATE_SGI)
5798 {
5799 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5800 }
5801 if (rate_flags & eHAL_TX_RATE_HT40)
5802 {
5803 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5804 }
5805#ifdef LINKSPEED_DEBUG_ENABLED
5806 pr_info("Reporting MCS rate %d flags %x\n",
5807 sinfo->txrate.mcs,
5808 sinfo->txrate.flags );
5809#endif //LINKSPEED_DEBUG_ENABLED
5810 }
5811 }
5812 else
5813 {
5814 // report current rate instead of max rate
5815
5816 if (rate_flags & eHAL_TX_RATE_LEGACY)
5817 {
5818 //provide to the UI in units of 100kbps
5819 sinfo->txrate.legacy = myRate;
5820#ifdef LINKSPEED_DEBUG_ENABLED
5821 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
5822#endif //LINKSPEED_DEBUG_ENABLED
5823 }
5824 else
5825 {
5826 //must be MCS
5827 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5828 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5829 if (rate_flags & eHAL_TX_RATE_SGI)
5830 {
5831 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5832 }
5833 if (rate_flags & eHAL_TX_RATE_HT40)
5834 {
5835 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5836 }
5837#ifdef LINKSPEED_DEBUG_ENABLED
5838 pr_info("Reporting actual MCS rate %d flags %x\n",
5839 sinfo->txrate.mcs,
5840 sinfo->txrate.flags );
5841#endif //LINKSPEED_DEBUG_ENABLED
5842 }
5843 }
5844 sinfo->filled |= STATION_INFO_TX_BITRATE;
5845
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005846 sinfo->tx_packets =
5847 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
5848 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
5849 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
5850 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
5851
5852 sinfo->tx_retries =
5853 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
5854 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
5855 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
5856 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
5857
5858 sinfo->tx_failed =
5859 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
5860 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
5861 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
5862 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
5863
5864 sinfo->filled |=
5865 STATION_INFO_TX_PACKETS |
5866 STATION_INFO_TX_RETRIES |
5867 STATION_INFO_TX_FAILED;
5868
5869 EXIT();
5870 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005871}
5872
5873static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
5874 struct net_device *dev, bool mode, v_SINT_t timeout)
5875{
5876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5877 VOS_STATUS vos_status;
5878
Jeff Johnsone7245742012-09-05 17:12:55 -07005879 ENTER();
5880
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 if (NULL == pAdapter)
5882 {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5884 return -ENODEV;
5885 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005886 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5887 {
5888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5889 "%s:LOGP in Progress. Ignore!!!", __func__);
5890 return -EAGAIN;
5891 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005892
5893 /**The get power cmd from the supplicant gets updated by the nl only
5894 *on successful execution of the function call
5895 *we are oppositely mapped w.r.t mode in the driver
5896 **/
5897 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
5898
Jeff Johnsone7245742012-09-05 17:12:55 -07005899 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 if (VOS_STATUS_E_FAILURE == vos_status)
5901 {
5902 return -EINVAL;
5903 }
5904 return 0;
5905}
5906
5907
5908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5909static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
5910 struct net_device *netdev,
5911 u8 key_index)
5912{
Jeff Johnsone7245742012-09-05 17:12:55 -07005913 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 return 0;
5915}
5916#endif //LINUX_VERSION_CODE
5917
5918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5919static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5920 struct net_device *dev,
5921 struct ieee80211_txq_params *params)
5922{
Jeff Johnsone7245742012-09-05 17:12:55 -07005923 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 return 0;
5925}
5926#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5927static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5928 struct ieee80211_txq_params *params)
5929{
Jeff Johnsone7245742012-09-05 17:12:55 -07005930 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 return 0;
5932}
5933#endif //LINUX_VERSION_CODE
5934
5935static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
5936 struct net_device *dev, u8 *mac)
5937{
5938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5939
Jeff Johnsone7245742012-09-05 17:12:55 -07005940 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
5942 {
5943 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
5944 return -EINVAL;
5945 }
5946
5947 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
5948 {
5949 hddLog( LOGE,
5950 "%s: Wlan Load/Unload is in progress", __func__);
5951 return -EBUSY;
5952 }
5953
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005954 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5955 {
5956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5957 "%s:LOGP in Progress. Ignore!!!", __func__);
5958 return -EAGAIN;
5959 }
5960
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
5962#ifdef WLAN_FEATURE_P2P
5963 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5964#endif
5965 )
5966 {
5967 if( NULL == mac )
5968 {
5969 v_U16_t i;
5970 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
5971 {
5972 if(pAdapter->aStaInfo[i].isUsed)
5973 {
5974 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
5975 hddLog(VOS_TRACE_LEVEL_INFO,
5976 "%s: Delete STA with MAC::"
5977 "%02x:%02x:%02x:%02x:%02x:%02x",
5978 __func__,
5979 macAddr[0], macAddr[1], macAddr[2],
5980 macAddr[3], macAddr[4], macAddr[5]);
5981 hdd_softap_sta_deauth(pAdapter, macAddr);
5982 }
5983 }
5984 }
5985 else
5986 {
5987 hddLog(VOS_TRACE_LEVEL_INFO,
5988 "%s: Delete STA with MAC::"
5989 "%02x:%02x:%02x:%02x:%02x:%02x",
5990 __func__,
5991 mac[0], mac[1], mac[2],
5992 mac[3], mac[4], mac[5]);
5993 hdd_softap_sta_deauth(pAdapter, mac);
5994 }
5995 }
5996
5997 EXIT();
5998
5999 return 0;
6000}
6001
6002static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6003 struct net_device *dev, u8 *mac, struct station_parameters *params)
6004{
6005 // TODO: Implement this later.
Jeff Johnsone7245742012-09-05 17:12:55 -07006006 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 return 0;
6008}
6009
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006010
6011#ifdef FEATURE_WLAN_LFR
6012static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006013 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006014{
6015#define MAX_PMKSAIDS_IN_CACHE 8
6016 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006017 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006018 tANI_U32 j=0;
6019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6020 tHalHandle halHandle;
6021 eHalStatus result;
6022 tANI_U8 BSSIDMatched = 0;
6023
Jeff Johnsone7245742012-09-05 17:12:55 -07006024 ENTER();
6025
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006026 // Validate pAdapter
6027 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6028 {
6029 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6030 return -EINVAL;
6031 }
6032
6033 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6034 {
6035 hddLog( LOGE,
6036 "%s: Wlan Load/Unload is in progress", __func__);
6037 return -EBUSY;
6038 }
6039
6040 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6041 {
6042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6043 "%s:LOGP in Progress. Ignore!!!", __func__);
6044 return -EAGAIN;
6045 }
6046
6047 // Retrieve halHandle
6048 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6049
6050 for (j = 0; j < i; j++)
6051 {
6052 if(vos_mem_compare(PMKIDCache[j].BSSID,
6053 pmksa->bssid, WNI_CFG_BSSID_LEN))
6054 {
6055 /* BSSID matched previous entry. Overwrite it. */
6056 BSSIDMatched = 1;
6057 vos_mem_copy(PMKIDCache[j].BSSID,
6058 pmksa->bssid, WNI_CFG_BSSID_LEN);
6059 vos_mem_copy(PMKIDCache[j].PMKID,
6060 pmksa->pmkid,
6061 CSR_RSN_PMKID_SIZE);
6062 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006063 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006064 dump_bssid(pmksa->bssid);
6065 dump_pmkid(halHandle, pmksa->pmkid);
6066 break;
6067 }
6068 }
6069
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006070 /* Check we compared all entries,if then take the first slot now */
6071 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6072
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006073 if (!BSSIDMatched)
6074 {
6075 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6076 vos_mem_copy(PMKIDCache[i].BSSID,
6077 pmksa->bssid, ETHER_ADDR_LEN);
6078 vos_mem_copy(PMKIDCache[i].PMKID,
6079 pmksa->pmkid,
6080 CSR_RSN_PMKID_SIZE);
6081 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006082 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006083 dump_bssid(pmksa->bssid);
6084 dump_pmkid(halHandle, pmksa->pmkid);
6085 // Increment the HDD Local Cache index
6086 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6087 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6088 }
6089
6090
6091 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6092 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006093 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006094 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006095 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006096 // Finally set the PMKSA ID Cache in CSR
6097 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6098 PMKIDCache,
6099 i );
6100 return 0;
6101}
6102
6103
6104static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006105 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006106{
Jeff Johnsone7245742012-09-05 17:12:55 -07006107 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006108 // TODO: Implement this later.
6109 return 0;
6110}
6111
6112static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6113{
Jeff Johnsone7245742012-09-05 17:12:55 -07006114 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006115 // TODO: Implement this later.
6116 return 0;
6117}
6118#endif
6119
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006120#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6121static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6122 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6123{
6124 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6125 hdd_station_ctx_t *pHddStaCtx;
6126
6127 if (NULL == pAdapter)
6128 {
6129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6130 return -ENODEV;
6131 }
6132
6133 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6134
6135 // Added for debug on reception of Re-assoc Req.
6136 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6137 {
6138 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6139 ftie->ie_len);
6140 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6141 }
6142
6143#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6144 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6145 ftie->ie_len);
6146#endif
6147
6148 // Pass the received FT IEs to SME
6149 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6150 ftie->ie_len);
6151 return 0;
6152}
6153#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006154
Jeff Johnson295189b2012-06-20 16:38:30 -07006155/* cfg80211_ops */
6156static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6157{
6158 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6159 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6160 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6161 .change_station = wlan_hdd_change_station,
6162#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6163 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6164 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6165 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006166#else
6167 .start_ap = wlan_hdd_cfg80211_start_ap,
6168 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6169 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006170#endif
6171 .change_bss = wlan_hdd_cfg80211_change_bss,
6172 .add_key = wlan_hdd_cfg80211_add_key,
6173 .get_key = wlan_hdd_cfg80211_get_key,
6174 .del_key = wlan_hdd_cfg80211_del_key,
6175 .set_default_key = wlan_hdd_cfg80211_set_default_key,
6176 .set_channel = wlan_hdd_cfg80211_set_channel,
6177 .scan = wlan_hdd_cfg80211_scan,
6178 .connect = wlan_hdd_cfg80211_connect,
6179 .disconnect = wlan_hdd_cfg80211_disconnect,
6180 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6181 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6182 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6183 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6184 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6185#ifdef WLAN_FEATURE_P2P
6186 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6187 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6188 .mgmt_tx = wlan_hdd_action,
6189#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6190 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6191 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6192 .set_txq_params = wlan_hdd_set_txq_params,
6193#endif
6194#endif
6195 .get_station = wlan_hdd_cfg80211_get_station,
6196 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6197 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006198 .add_station = wlan_hdd_cfg80211_add_station,
6199#ifdef FEATURE_WLAN_LFR
6200 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6201 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6202 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6203#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006204#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6205 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6206#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006207};
6208
6209#endif // CONFIG_CFG80211