blob: 70e6fe910241eee9cd0846a2ce0efeb4698b5f08 [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>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080084#ifdef FEATURE_WLAN_TDLS
85#include "wlan_hdd_tdls.h"
86#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070087
88#define g_mode_rates_size (12)
89#define a_mode_rates_size (8)
90#define FREQ_BASE_80211G (2407)
91#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070092#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070093#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
94 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
95
96#define HDD2GHZCHAN(freq, chan, flag) { \
97 .band = IEEE80211_BAND_2GHZ, \
98 .center_freq = (freq), \
99 .hw_value = (chan),\
100 .flags = (flag), \
101 .max_antenna_gain = 0 ,\
102 .max_power = 30, \
103}
104
105#define HDD5GHZCHAN(freq, chan, flag) { \
106 .band = IEEE80211_BAND_5GHZ, \
107 .center_freq = (freq), \
108 .hw_value = (chan),\
109 .flags = (flag), \
110 .max_antenna_gain = 0 ,\
111 .max_power = 30, \
112}
113
114#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
115{\
116 .bitrate = rate, \
117 .hw_value = rate_id, \
118 .flags = flag, \
119}
120
121static const u32 hdd_cipher_suites[] =
122{
123 WLAN_CIPHER_SUITE_WEP40,
124 WLAN_CIPHER_SUITE_WEP104,
125 WLAN_CIPHER_SUITE_TKIP,
126#ifdef FEATURE_WLAN_CCX
127#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
128 WLAN_CIPHER_SUITE_KRK,
129 WLAN_CIPHER_SUITE_CCMP,
130#else
131 WLAN_CIPHER_SUITE_CCMP,
132#endif
133#ifdef FEATURE_WLAN_WAPI
134 WLAN_CIPHER_SUITE_SMS4,
135#endif
136};
137
138static inline int is_broadcast_ether_addr(const u8 *addr)
139{
140 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
141 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
142}
143
144static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
145{
146 HDD2GHZCHAN(2412, 1, 0) ,
147 HDD2GHZCHAN(2417, 2, 0) ,
148 HDD2GHZCHAN(2422, 3, 0) ,
149 HDD2GHZCHAN(2427, 4, 0) ,
150 HDD2GHZCHAN(2432, 5, 0) ,
151 HDD2GHZCHAN(2437, 6, 0) ,
152 HDD2GHZCHAN(2442, 7, 0) ,
153 HDD2GHZCHAN(2447, 8, 0) ,
154 HDD2GHZCHAN(2452, 9, 0) ,
155 HDD2GHZCHAN(2457, 10, 0) ,
156 HDD2GHZCHAN(2462, 11, 0) ,
157 HDD2GHZCHAN(2467, 12, 0) ,
158 HDD2GHZCHAN(2472, 13, 0) ,
159 HDD2GHZCHAN(2484, 14, 0) ,
160};
161
162#ifdef WLAN_FEATURE_P2P
163static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
164{
165 HDD2GHZCHAN(2412, 1, 0) ,
166 HDD2GHZCHAN(2437, 6, 0) ,
167 HDD2GHZCHAN(2462, 11, 0) ,
168};
169#endif
170
171static struct ieee80211_channel hdd_channels_5_GHZ[] =
172{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700173 HDD5GHZCHAN(4920, 240, 0) ,
174 HDD5GHZCHAN(4940, 244, 0) ,
175 HDD5GHZCHAN(4960, 248, 0) ,
176 HDD5GHZCHAN(4980, 252, 0) ,
177 HDD5GHZCHAN(5040, 208, 0) ,
178 HDD5GHZCHAN(5060, 212, 0) ,
179 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700180 HDD5GHZCHAN(5180, 36, 0) ,
181 HDD5GHZCHAN(5200, 40, 0) ,
182 HDD5GHZCHAN(5220, 44, 0) ,
183 HDD5GHZCHAN(5240, 48, 0) ,
184 HDD5GHZCHAN(5260, 52, 0) ,
185 HDD5GHZCHAN(5280, 56, 0) ,
186 HDD5GHZCHAN(5300, 60, 0) ,
187 HDD5GHZCHAN(5320, 64, 0) ,
188 HDD5GHZCHAN(5500,100, 0) ,
189 HDD5GHZCHAN(5520,104, 0) ,
190 HDD5GHZCHAN(5540,108, 0) ,
191 HDD5GHZCHAN(5560,112, 0) ,
192 HDD5GHZCHAN(5580,116, 0) ,
193 HDD5GHZCHAN(5600,120, 0) ,
194 HDD5GHZCHAN(5620,124, 0) ,
195 HDD5GHZCHAN(5640,128, 0) ,
196 HDD5GHZCHAN(5660,132, 0) ,
197 HDD5GHZCHAN(5680,136, 0) ,
198 HDD5GHZCHAN(5700,140, 0) ,
199 HDD5GHZCHAN(5745,149, 0) ,
200 HDD5GHZCHAN(5765,153, 0) ,
201 HDD5GHZCHAN(5785,157, 0) ,
202 HDD5GHZCHAN(5805,161, 0) ,
203 HDD5GHZCHAN(5825,165, 0) ,
204};
205
206static struct ieee80211_rate g_mode_rates[] =
207{
208 HDD_G_MODE_RATETAB(10, 0x1, 0),
209 HDD_G_MODE_RATETAB(20, 0x2, 0),
210 HDD_G_MODE_RATETAB(55, 0x4, 0),
211 HDD_G_MODE_RATETAB(110, 0x8, 0),
212 HDD_G_MODE_RATETAB(60, 0x10, 0),
213 HDD_G_MODE_RATETAB(90, 0x20, 0),
214 HDD_G_MODE_RATETAB(120, 0x40, 0),
215 HDD_G_MODE_RATETAB(180, 0x80, 0),
216 HDD_G_MODE_RATETAB(240, 0x100, 0),
217 HDD_G_MODE_RATETAB(360, 0x200, 0),
218 HDD_G_MODE_RATETAB(480, 0x400, 0),
219 HDD_G_MODE_RATETAB(540, 0x800, 0),
220};
221
222static struct ieee80211_rate a_mode_rates[] =
223{
224 HDD_G_MODE_RATETAB(60, 0x10, 0),
225 HDD_G_MODE_RATETAB(90, 0x20, 0),
226 HDD_G_MODE_RATETAB(120, 0x40, 0),
227 HDD_G_MODE_RATETAB(180, 0x80, 0),
228 HDD_G_MODE_RATETAB(240, 0x100, 0),
229 HDD_G_MODE_RATETAB(360, 0x200, 0),
230 HDD_G_MODE_RATETAB(480, 0x400, 0),
231 HDD_G_MODE_RATETAB(540, 0x800, 0),
232};
233
234static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
235{
236 .channels = hdd_channels_2_4_GHZ,
237 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
238 .band = IEEE80211_BAND_2GHZ,
239 .bitrates = g_mode_rates,
240 .n_bitrates = g_mode_rates_size,
241 .ht_cap.ht_supported = 1,
242 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
243 | IEEE80211_HT_CAP_GRN_FLD
244 | IEEE80211_HT_CAP_DSSSCCK40
245 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
246 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
247 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
248 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
249 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
250 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
251};
252
253#ifdef WLAN_FEATURE_P2P
254static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
255{
256 .channels = hdd_social_channels_2_4_GHZ,
257 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
258 .band = IEEE80211_BAND_2GHZ,
259 .bitrates = g_mode_rates,
260 .n_bitrates = g_mode_rates_size,
261 .ht_cap.ht_supported = 1,
262 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
263 | IEEE80211_HT_CAP_GRN_FLD
264 | IEEE80211_HT_CAP_DSSSCCK40
265 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
266 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
267 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
268 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
269 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
270 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
271};
272#endif
273
274static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
275{
276 .channels = hdd_channels_5_GHZ,
277 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
278 .band = IEEE80211_BAND_5GHZ,
279 .bitrates = a_mode_rates,
280 .n_bitrates = a_mode_rates_size,
281 .ht_cap.ht_supported = 1,
282 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
283 | IEEE80211_HT_CAP_GRN_FLD
284 | IEEE80211_HT_CAP_DSSSCCK40
285 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
286 | IEEE80211_HT_CAP_SGI_40
287 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
288 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
289 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
290 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
291 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
292 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
293};
294
295/* This structure contain information what kind of frame are expected in
296 TX/RX direction for each kind of interface */
297static const struct ieee80211_txrx_stypes
298wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
299 [NL80211_IFTYPE_STATION] = {
300 .tx = 0xffff,
301 .rx = BIT(SIR_MAC_MGMT_ACTION) |
302 BIT(SIR_MAC_MGMT_PROBE_REQ),
303 },
304 [NL80211_IFTYPE_AP] = {
305 .tx = 0xffff,
306 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
307 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
308 BIT(SIR_MAC_MGMT_PROBE_REQ) |
309 BIT(SIR_MAC_MGMT_DISASSOC) |
310 BIT(SIR_MAC_MGMT_AUTH) |
311 BIT(SIR_MAC_MGMT_DEAUTH) |
312 BIT(SIR_MAC_MGMT_ACTION),
313 },
314#ifdef WLAN_FEATURE_P2P
315 [NL80211_IFTYPE_P2P_CLIENT] = {
316 .tx = 0xffff,
317 .rx = BIT(SIR_MAC_MGMT_ACTION) |
318 BIT(SIR_MAC_MGMT_PROBE_REQ),
319 },
320 [NL80211_IFTYPE_P2P_GO] = {
321 /* This is also same as for SoftAP */
322 .tx = 0xffff,
323 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
324 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
325 BIT(SIR_MAC_MGMT_PROBE_REQ) |
326 BIT(SIR_MAC_MGMT_DISASSOC) |
327 BIT(SIR_MAC_MGMT_AUTH) |
328 BIT(SIR_MAC_MGMT_DEAUTH) |
329 BIT(SIR_MAC_MGMT_ACTION),
330 },
331#endif
332};
333
334static struct cfg80211_ops wlan_hdd_cfg80211_ops;
335
336/* Data rate 100KBPS based on IE Index */
337struct index_data_rate_type
338{
339 v_U8_t beacon_rate_index;
340 v_U16_t supported_rate[4];
341};
342
343/* 11B, 11G Rate table include Basic rate and Extended rate
344 The IDX field is the rate index
345 The HI field is the rate when RSSI is strong or being ignored
346 (in this case we report actual rate)
347 The MID field is the rate when RSSI is moderate
348 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
349 The LO field is the rate when RSSI is low
350 (in this case we don't report rates, actual current rate used)
351 */
352static const struct
353{
354 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700355 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700356} supported_data_rate[] =
357{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700358/* IDX HI HM LM LO (RSSI-based index */
359 {2, { 10, 10, 10, 0}},
360 {4, { 20, 20, 10, 0}},
361 {11, { 55, 20, 10, 0}},
362 {12, { 60, 55, 20, 0}},
363 {18, { 90, 55, 20, 0}},
364 {22, {110, 55, 20, 0}},
365 {24, {120, 90, 60, 0}},
366 {36, {180, 120, 60, 0}},
367 {44, {220, 180, 60, 0}},
368 {48, {240, 180, 90, 0}},
369 {66, {330, 180, 90, 0}},
370 {72, {360, 240, 90, 0}},
371 {96, {480, 240, 120, 0}},
372 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700373};
374
375/* MCS Based rate table */
376static struct index_data_rate_type supported_mcs_rate[] =
377{
378/* MCS L20 L40 S20 S40 */
379 {0, {65, 135, 72, 150}},
380 {1, {130, 270, 144, 300}},
381 {2, {195, 405, 217, 450}},
382 {3, {260, 540, 289, 600}},
383 {4, {390, 810, 433, 900}},
384 {5, {520, 1080, 578, 1200}},
385 {6, {585, 1215, 650, 1350}},
386 {7, {650, 1350, 722, 1500}}
387};
388
389extern struct net_device_ops net_ops_struct;
390
391/*
392 * FUNCTION: wlan_hdd_cfg80211_init
393 * This function is called by hdd_wlan_startup()
394 * during initialization.
395 * This function is used to initialize and register wiphy structure.
396 */
397struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
398{
399 struct wiphy *wiphy;
400 ENTER();
401
402 /*
403 * Create wiphy device
404 */
405 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
406
407 if (!wiphy)
408 {
409 /* Print error and jump into err label and free the memory */
410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
411 return NULL;
412 }
413
414 return wiphy;
415}
416
417/*
418 * FUNCTION: wlan_hdd_cfg80211_update_band
419 * This function is called from the supplicant through a
420 * private ioctl to change the band value
421 */
422int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
423{
Jeff Johnsone7245742012-09-05 17:12:55 -0700424 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700425 switch(eBand)
426 {
427 case eCSR_BAND_24:
428 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
429 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
430 break;
431 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700432#ifdef WLAN_FEATURE_P2P
433 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
434#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700435 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700436#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700437 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
438 break;
439 case eCSR_BAND_ALL:
440 default:
441 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
442 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
443 }
444 return 0;
445}
446/*
447 * FUNCTION: wlan_hdd_cfg80211_init
448 * This function is called by hdd_wlan_startup()
449 * during initialization.
450 * This function is used to initialize and register wiphy structure.
451 */
452int wlan_hdd_cfg80211_register(struct device *dev,
453 struct wiphy *wiphy,
454 hdd_config_t *pCfg
455 )
456{
Jeff Johnsone7245742012-09-05 17:12:55 -0700457 ENTER();
458
Jeff Johnson295189b2012-06-20 16:38:30 -0700459 /* Now bind the underlying wlan device with wiphy */
460 set_wiphy_dev(wiphy, dev);
461
462 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
463
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700464 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700465
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700467 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
468 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
469 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700470 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700471#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800472#ifdef FEATURE_WLAN_TDLS
473 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
474 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
475#endif
476
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700477 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
478 driver can still register regulatory callback and
479 it will get CRDA setting in wiphy->band[], but
480 driver need to determine what to do with both
481 regulatory settings */
482 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700483
Jeff Johnson295189b2012-06-20 16:38:30 -0700484 wiphy->max_scan_ssids = MAX_SCAN_SSID;
485
486 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
487
488 /* Supports STATION & AD-HOC modes right now */
489 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
490 | BIT(NL80211_IFTYPE_ADHOC)
491#ifdef WLAN_FEATURE_P2P
492 | BIT(NL80211_IFTYPE_P2P_CLIENT)
493 | BIT(NL80211_IFTYPE_P2P_GO)
494#endif
495 | BIT(NL80211_IFTYPE_AP);
496
497 /* Before registering we need to update the ht capabilitied based
498 * on ini values*/
499 if( !pCfg->ShortGI20MhzEnable )
500 {
501 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
502 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
503 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
504 }
505
506 if( !pCfg->ShortGI40MhzEnable )
507 {
508 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
509 }
510
511 if( !pCfg->nChannelBondingMode5GHz )
512 {
513 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
514 }
515
516 /*Initialize band capability*/
517 switch(pCfg->nBandCapability)
518 {
519 case eCSR_BAND_24:
520 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
521 break;
522 case eCSR_BAND_5G:
523#ifdef WLAN_FEATURE_P2P
524 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
525#endif
526 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
527 break;
528 case eCSR_BAND_ALL:
529 default:
530 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
531 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
532 }
533 /*Initialise the supported cipher suite details*/
534 wiphy->cipher_suites = hdd_cipher_suites;
535 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
536
537 /*signal strength in mBm (100*dBm) */
538 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
539
540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
541#ifdef WLAN_FEATURE_P2P
542 wiphy->max_remain_on_channel_duration = 1000;
543#endif
544#endif
545
546 /* Register our wiphy dev with cfg80211 */
547 if (0 > wiphy_register(wiphy))
548 {
549 /* print eror */
550 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
551 return -EIO;
552 }
553
554 EXIT();
555 return 0;
556}
557
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700558/* In this function we will try to get default country code from crda.
559 If the gCrdaDefaultCountryCode is configured in ini file,
560 we will try to call user space crda to get the regulatory settings for
561 that country. We will timeout if we can't get it from crda.
562 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
563*/
564int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
565{
566 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
567 if (memcmp(pCfg->crdaDefaultCountryCode,
568 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
569 {
570 init_completion(&pHddCtx->driver_crda_req);
571 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
572 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
573 CRDA_WAIT_TIME);
574 }
575 return 0;
576}
577
Jeff Johnson295189b2012-06-20 16:38:30 -0700578/* In this function we will do all post VOS start initialization.
579 In this function we will register for all frame in which supplicant
580 is interested.
581*/
582void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
583{
584#ifdef WLAN_FEATURE_P2P
585 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
586 /* Register for all P2P action, public action etc frames */
587 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
588
Jeff Johnsone7245742012-09-05 17:12:55 -0700589 ENTER();
590
Jeff Johnson295189b2012-06-20 16:38:30 -0700591 /* Right now we are registering these frame when driver is getting
592 initialized. Once we will move to 2.6.37 kernel, in which we have
593 frame register ops, we will move this code as a part of that */
594 /* GAS Initial Request */
595 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
596 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
597
598 /* GAS Initial Response */
599 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
600 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
601
602 /* GAS Comeback Request */
603 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
604 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
605
606 /* GAS Comeback Response */
607 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
608 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
609
610 /* P2P Public Action */
611 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
612 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
613 P2P_PUBLIC_ACTION_FRAME_SIZE );
614
615 /* P2P Action */
616 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
617 (v_U8_t*)P2P_ACTION_FRAME,
618 P2P_ACTION_FRAME_SIZE );
619#endif /* WLAN_FEATURE_P2P */
620}
621
622void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
623{
624#ifdef WLAN_FEATURE_P2P
625 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
626 /* Register for all P2P action, public action etc frames */
627 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
628
Jeff Johnsone7245742012-09-05 17:12:55 -0700629 ENTER();
630
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 /* Right now we are registering these frame when driver is getting
632 initialized. Once we will move to 2.6.37 kernel, in which we have
633 frame register ops, we will move this code as a part of that */
634 /* GAS Initial Request */
635
636 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
637 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
638
639 /* GAS Initial Response */
640 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
641 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
642
643 /* GAS Comeback Request */
644 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
645 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
646
647 /* GAS Comeback Response */
648 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
649 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
650
651 /* P2P Public Action */
652 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
653 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
654 P2P_PUBLIC_ACTION_FRAME_SIZE );
655
656 /* P2P Action */
657 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
658 (v_U8_t*)P2P_ACTION_FRAME,
659 P2P_ACTION_FRAME_SIZE );
660#endif /* WLAN_FEATURE_P2P */
661}
662
663#ifdef FEATURE_WLAN_WAPI
664void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
665 const u8 *mac_addr, u8 *key , int key_Len)
666{
667 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
668 tCsrRoamSetKey setKey;
669 v_BOOL_t isConnected = TRUE;
670 int status = 0;
671 v_U32_t roamId= 0xFF;
672 tANI_U8 *pKeyPtr = NULL;
673 int n = 0;
674
675 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
676 __func__,pAdapter->device_mode);
677
678 setKey.keyId = key_index; // Store Key ID
679 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
680 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
681 setKey.paeRole = 0 ; // the PAE role
682 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
683 {
684 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
685 }
686 else
687 {
688 isConnected = hdd_connIsConnected(pHddStaCtx);
689 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
690 }
691 setKey.keyLength = key_Len;
692 pKeyPtr = setKey.Key;
693 memcpy( pKeyPtr, key, key_Len);
694
695 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
696 __func__, key_Len);
697 for (n = 0 ; n < key_Len; n++)
698 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
699 __func__,n,setKey.Key[n]);
700
701 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
702 if ( isConnected )
703 {
704 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
705 pAdapter->sessionId, &setKey, &roamId );
706 }
707 if ( status != 0 )
708 {
709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
710 "[%4d] sme_RoamSetKey returned ERROR status= %d",
711 __LINE__, status );
712 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
713 }
714}
715#endif /* FEATURE_WLAN_WAPI*/
716
717#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
718int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
719 beacon_data_t **ppBeacon,
720 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700721#else
722int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
723 beacon_data_t **ppBeacon,
724 struct cfg80211_beacon_data *params,
725 int dtim_period)
726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700727{
728 int size;
729 beacon_data_t *beacon = NULL;
730 beacon_data_t *old = NULL;
731 int head_len,tail_len;
732
Jeff Johnsone7245742012-09-05 17:12:55 -0700733 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700734 if (params->head && !params->head_len)
735 return -EINVAL;
736
737 old = pAdapter->sessionCtx.ap.beacon;
738
739 if (!params->head && !old)
740 return -EINVAL;
741
742 if (params->tail && !params->tail_len)
743 return -EINVAL;
744
745#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
746 /* Kernel 3.0 is not updating dtim_period for set beacon */
747 if (!params->dtim_period)
748 return -EINVAL;
749#endif
750
751 if(params->head)
752 head_len = params->head_len;
753 else
754 head_len = old->head_len;
755
756 if(params->tail || !old)
757 tail_len = params->tail_len;
758 else
759 tail_len = old->tail_len;
760
761 size = sizeof(beacon_data_t) + head_len + tail_len;
762
763 beacon = kzalloc(size, GFP_KERNEL);
764
765 if( beacon == NULL )
766 return -ENOMEM;
767
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700768#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700769 if(params->dtim_period || !old )
770 beacon->dtim_period = params->dtim_period;
771 else
772 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700773#else
774 if(dtim_period || !old )
775 beacon->dtim_period = dtim_period;
776 else
777 beacon->dtim_period = old->dtim_period;
778#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700779
780 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
781 beacon->tail = beacon->head + head_len;
782 beacon->head_len = head_len;
783 beacon->tail_len = tail_len;
784
785 if(params->head) {
786 memcpy (beacon->head,params->head,beacon->head_len);
787 }
788 else {
789 if(old)
790 memcpy (beacon->head,old->head,beacon->head_len);
791 }
792
793 if(params->tail) {
794 memcpy (beacon->tail,params->tail,beacon->tail_len);
795 }
796 else {
797 if(old)
798 memcpy (beacon->tail,old->tail,beacon->tail_len);
799 }
800
801 *ppBeacon = beacon;
802
803 kfree(old);
804
805 return 0;
806
807}
Jeff Johnson295189b2012-06-20 16:38:30 -0700808
809v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
810{
811 int left = length;
812 v_U8_t *ptr = pIes;
813 v_U8_t elem_id,elem_len;
814
815 while(left >= 2)
816 {
817 elem_id = ptr[0];
818 elem_len = ptr[1];
819 left -= 2;
820 if(elem_len > left)
821 {
822 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700823 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700824 eid,elem_len,left);
825 return NULL;
826 }
827 if (elem_id == eid)
828 {
829 return ptr;
830 }
831
832 left -= elem_len;
833 ptr += (elem_len + 2);
834 }
835 return NULL;
836}
837
Jeff Johnson295189b2012-06-20 16:38:30 -0700838/* Check if rate is 11g rate or not */
839static int wlan_hdd_rate_is_11g(u8 rate)
840{
841 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
842 u8 i;
843 for (i = 0; i < 8; i++)
844 {
845 if(rate == gRateArray[i])
846 return TRUE;
847 }
848 return FALSE;
849}
850
851/* Check for 11g rate and set proper 11g only mode */
852static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
853 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
854{
855 u8 i, num_rates = pIe[0];
856
857 pIe += 1;
858 for ( i = 0; i < num_rates; i++)
859 {
860 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
861 {
862 /* If rate set have 11g rate than change the mode to 11G */
863 *pSapHw_mode = eSAP_DOT11_MODE_11g;
864 if (pIe[i] & BASIC_RATE_MASK)
865 {
866 /* If we have 11g rate as basic rate, it means mode
867 is 11g only mode.
868 */
869 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
870 *pCheckRatesfor11g = FALSE;
871 }
872 }
873 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
874 {
875 *require_ht = TRUE;
876 }
877 }
878 return;
879}
880
881static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
882{
883 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
884 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
885 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
886 u8 checkRatesfor11g = TRUE;
887 u8 require_ht = FALSE;
888 u8 *pIe=NULL;
889
890 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
891
892 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
893 pBeacon->head_len, WLAN_EID_SUPP_RATES);
894 if (pIe != NULL)
895 {
896 pIe += 1;
897 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
898 &pConfig->SapHw_mode);
899 }
900
901 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
902 WLAN_EID_EXT_SUPP_RATES);
903 if (pIe != NULL)
904 {
905
906 pIe += 1;
907 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
908 &pConfig->SapHw_mode);
909 }
910
911 if( pConfig->channel > 14 )
912 {
913 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
914 }
915
916 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
917 WLAN_EID_HT_CAPABILITY);
918
919 if(pIe)
920 {
921 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
922 if(require_ht)
923 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
924 }
925}
926
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700927#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700928static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
929 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700930#else
931static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
932 struct cfg80211_beacon_data *params)
933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700934{
935 v_U8_t *genie;
936 v_U8_t total_ielen = 0, ielen = 0;
937 v_U8_t *pIe = NULL;
938 v_U8_t addIE[1] = {0};
939 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -0700940 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700941
942 genie = vos_mem_malloc(MAX_GENIE_LEN);
943
944 if(genie == NULL) {
945
946 return -ENOMEM;
947 }
948
949 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
950
951 if(pIe)
952 {
953 /*Copy the wps IE*/
954 ielen = pIe[1] + 2;
955 if( ielen <=MAX_GENIE_LEN)
956 {
957 vos_mem_copy(genie, pIe, ielen);
958 }
959 else
960 {
961 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700962 ret = -EINVAL;
963 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 }
965 total_ielen = ielen;
966 }
967
968#ifdef WLAN_FEATURE_WFD
969 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
970
971 if(pIe)
972 {
973 ielen = pIe[1] + 2;
974 if(total_ielen + ielen <= MAX_GENIE_LEN) {
975 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
976 }
977 else {
978 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -0700979 ret = -EINVAL;
980 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 }
982 total_ielen += ielen;
983 }
984#endif
985
986#ifdef WLAN_FEATURE_P2P
987 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
988
989 if(pIe)
990 {
991 ielen = pIe[1] + 2;
992 if(total_ielen + ielen <= MAX_GENIE_LEN)
993 {
994 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
995 }
996 else
997 {
998 hddLog( VOS_TRACE_LEVEL_ERROR,
999 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001000 ret = -EINVAL;
1001 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 }
1003 total_ielen += ielen;
1004 }
1005#endif
1006
1007 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1008 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1009 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1010 {
1011 hddLog(LOGE,
1012 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001013 ret = -EINVAL;
1014 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 }
1016
1017 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1018 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1019 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1020 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1021 ==eHAL_STATUS_FAILURE)
1022 {
1023 hddLog(LOGE,
1024 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001025 ret = -EINVAL;
1026 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001027 }
1028
1029 // Added for ProResp IE
1030 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1031 {
1032 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1033 u8 probe_rsp_ie_len[3] = {0};
1034 u8 counter = 0;
1035 /* Check Probe Resp Length if it is greater then 255 then Store
1036 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1037 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1038 Store More then 255 bytes into One Variable.
1039 */
1040 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1041 {
1042 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1043 {
1044 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1045 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1046 }
1047 else
1048 {
1049 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1050 rem_probe_resp_ie_len = 0;
1051 }
1052 }
1053
1054 rem_probe_resp_ie_len = 0;
1055
1056 if (probe_rsp_ie_len[0] > 0)
1057 {
1058 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1059 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1060 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1061 probe_rsp_ie_len[0], NULL,
1062 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1063 {
1064 hddLog(LOGE,
1065 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001066 ret = -EINVAL;
1067 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001068 }
1069 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1070 }
1071
1072 if (probe_rsp_ie_len[1] > 0)
1073 {
1074 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1075 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1076 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1077 probe_rsp_ie_len[1], NULL,
1078 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1079 {
1080 hddLog(LOGE,
1081 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001082 ret = -EINVAL;
1083 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 }
1085 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1086 }
1087
1088 if (probe_rsp_ie_len[2] > 0)
1089 {
1090 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1091 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1092 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1093 probe_rsp_ie_len[2], NULL,
1094 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1095 {
1096 hddLog(LOGE,
1097 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001098 ret = -EINVAL;
1099 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 }
1101 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1102 }
1103
1104 if (probe_rsp_ie_len[1] == 0 )
1105 {
1106 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1107 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1108 eANI_BOOLEAN_FALSE) )
1109 {
1110 hddLog(LOGE,
1111 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1112 }
1113 }
1114
1115 if (probe_rsp_ie_len[2] == 0 )
1116 {
1117 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1118 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1119 eANI_BOOLEAN_FALSE) )
1120 {
1121 hddLog(LOGE,
1122 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1123 }
1124 }
1125
1126 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1127 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1128 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1129 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1130 == eHAL_STATUS_FAILURE)
1131 {
1132 hddLog(LOGE,
1133 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001134 ret = -EINVAL;
1135 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001136 }
1137 }
1138 else
1139 {
1140 // Reset WNI_CFG_PROBE_RSP Flags
1141 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1142
1143 hddLog(VOS_TRACE_LEVEL_INFO,
1144 "%s: No Probe Response IE received in set beacon",
1145 __func__);
1146 }
1147
1148 // Added for AssocResp IE
1149 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1150 {
1151 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1152 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1153 params->assocresp_ies_len, NULL,
1154 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1155 {
1156 hddLog(LOGE,
1157 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001158 ret = -EINVAL;
1159 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001160 }
1161
1162 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1163 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1164 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1165 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1166 == eHAL_STATUS_FAILURE)
1167 {
1168 hddLog(LOGE,
1169 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001170 ret = -EINVAL;
1171 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 }
1173 }
1174 else
1175 {
1176 hddLog(VOS_TRACE_LEVEL_INFO,
1177 "%s: No Assoc Response IE received in set beacon",
1178 __func__);
1179
1180 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1181 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1182 eANI_BOOLEAN_FALSE) )
1183 {
1184 hddLog(LOGE,
1185 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1186 }
1187 }
1188
Jeff Johnsone7245742012-09-05 17:12:55 -07001189done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 vos_mem_free(genie);
1191 return 0;
1192}
Jeff Johnson295189b2012-06-20 16:38:30 -07001193
1194/*
1195 * FUNCTION: wlan_hdd_validate_operation_channel
1196 * called by wlan_hdd_cfg80211_start_bss() and
1197 * wlan_hdd_cfg80211_set_channel()
1198 * This function validates whether given channel is part of valid
1199 * channel list.
1200 */
1201static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1202{
1203
1204 v_U32_t num_ch = 0;
1205 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1206 u32 indx = 0;
1207 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1208
1209 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1210
1211 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1212 valid_ch, &num_ch))
1213 {
1214 hddLog(VOS_TRACE_LEVEL_ERROR,
1215 "%s: failed to get valid channel list\n", __func__);
1216 return VOS_STATUS_E_FAILURE;
1217 }
1218
1219 for (indx = 0; indx < num_ch; indx++)
1220 {
1221 if (channel == valid_ch[indx])
1222 {
1223 break;
1224 }
1225 }
1226
1227 if (indx >= num_ch)
1228 {
1229 hddLog(VOS_TRACE_LEVEL_ERROR,
1230 "%s: Invalid Channel [%d] \n", __func__, channel);
1231 return VOS_STATUS_E_FAILURE;
1232 }
1233 return VOS_STATUS_SUCCESS;
1234
1235}
1236
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301237/*
1238 * FUNCTION: wlan_hdd_select_cbmode
1239 * called by wlan_hdd_cfg80211_start_bss() and
1240 * This function selects the cbmode based on primary channel
1241 */
1242static VOS_STATUS wlan_hdd_select_cbmode(hdd_adapter_t *pAdapter,tsap_Config_t *pSapConfig )
1243{
1244 tSmeConfigParams smeConfig;
1245 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter->pHddCtx;
1246 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter->pHddCtx))->cfg_ini;
1247 v_U8_t channel;
1248
1249 if(
1250#ifdef WLAN_FEATURE_11AC
1251 pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11ac &&
1252 pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
1253#endif
1254 pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11n &&
1255 pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
1256 )
1257 {
1258 return VOS_STATUS_SUCCESS;
1259 }
1260
1261 if (!pConfigIni->nChannelBondingMode5GHz) {
1262 return VOS_STATUS_SUCCESS;
1263 }
1264
1265 channel = pSapConfig->channel;
1266 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1267
1268 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1269
1270#ifdef WLAN_FEATURE_11AC
1271
1272 if ( pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11ac ||
1273 pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
1274 {
1275 if ( channel== 36 || channel == 52 || channel == 100 ||
1276 channel == 116 || channel == 149 )
1277 {
1278 smeConfig.csrConfig.channelBondingMode5GHz =
1279 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1280 }
1281 else if ( channel == 40 || channel == 56 || channel == 104 ||
1282 channel == 120 || channel == 153 )
1283 {
1284 smeConfig.csrConfig.channelBondingMode5GHz =
1285 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1286 }
1287 else if ( channel == 44 || channel == 60 || channel == 108 ||
1288 channel == 124 || channel == 157 )
1289 {
1290 smeConfig.csrConfig.channelBondingMode5GHz =
1291 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1292 }
1293 else if ( channel == 48 || channel == 64 || channel == 112 ||
1294 channel == 128 || channel == 161 )
1295 {
1296 smeConfig.csrConfig.channelBondingMode5GHz =
1297 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1298 }
1299 else
1300 {
1301 smeConfig.csrConfig.channelBondingMode5GHz=0;
1302 }
1303 }
1304#endif
1305 if ( pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11n ||
1306 pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
1307 {
1308 if ( channel== 40 || channel == 48 || channel == 56 ||
1309 channel == 64 || channel == 104 || channel == 112 ||
1310 channel == 120 || channel == 128 || channel == 136 ||
1311 channel == 144 || channel == 153 || channel == 161 )
1312 {
1313 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1314 }
1315 else if ( channel== 36 || channel == 44 || channel == 52 ||
1316 channel == 60 || channel == 100 || channel == 108 ||
1317 channel == 116 || channel == 124 || channel == 132 ||
1318 channel == 140 || channel == 149 || channel == 157 )
1319 {
1320 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1321 }
1322 else
1323 {
1324 smeConfig.csrConfig.channelBondingMode5GHz=0;
1325 }
1326 }
1327 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1328
1329 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1330 return VOS_STATUS_SUCCESS;
1331}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001332
Jeff Johnson295189b2012-06-20 16:38:30 -07001333#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1334static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1335 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001336#else
1337static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1338 struct cfg80211_beacon_data *params,
1339 const u8 *ssid, size_t ssid_len,
1340 enum nl80211_hidden_ssid hidden_ssid)
1341#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001342{
1343 tsap_Config_t *pConfig;
1344 beacon_data_t *pBeacon = NULL;
1345 struct ieee80211_mgmt *pMgmt_frame;
1346 v_U8_t *pIe=NULL;
1347 v_U16_t capab_info;
1348 eCsrAuthType RSNAuthType;
1349 eCsrEncryptionType RSNEncryptType;
1350 eCsrEncryptionType mcRSNEncryptType;
1351 int status = VOS_STATUS_SUCCESS;
1352 tpWLAN_SAPEventCB pSapEventCallback;
1353 hdd_hostapd_state_t *pHostapdState;
1354 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1355 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1356 struct qc_mac_acl_entry *acl_entry = NULL;
1357 v_SINT_t i;
1358
1359 ENTER();
1360
1361 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1362
1363 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1364
1365 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1366
1367 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1368
1369 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1370
1371 //channel is already set in the set_channel Call back
1372 //pConfig->channel = pCommitConfig->channel;
1373
1374 /*Protection parameter to enable or disable*/
1375 pConfig->protEnabled =
1376 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1377
1378 pConfig->dtim_period = pBeacon->dtim_period;
1379
1380 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1381 pConfig->dtim_period);
1382
1383
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001384 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001385 {
1386 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001388 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001389 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001390 tANI_BOOLEAN restartNeeded;
1391 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1392 pConfig->ieee80211d = 1;
1393 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1394 sme_setRegInfo(hHal, pConfig->countryCode);
1395 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1396 /*
1397 * If auto channel is configured i.e. channel is 0,
1398 * so skip channel validation.
1399 */
1400 if( AUTO_CHANNEL_SELECT != pConfig->channel )
Jeff Johnson295189b2012-06-20 16:38:30 -07001401 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001402 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1403 {
1404 hddLog(VOS_TRACE_LEVEL_ERROR,
1405 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1406 return -EINVAL;
1407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001408 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001409 /*
1410 * Validate the given channel range for the given country code
1411 */
1412 else
1413 {
1414 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1415 WLANSAP_SetChannelRange(hHal,hdd_pConfig->apStartChannelNum,hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1416 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001418 else
1419 {
1420 pConfig->ieee80211d = 0;
1421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001422 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001423 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001424 {
1425 pConfig->ieee80211d = 0;
1426 }
1427 pConfig->authType = eSAP_AUTO_SWITCH;
1428
1429 capab_info = pMgmt_frame->u.beacon.capab_info;
1430
1431 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1432 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1433
1434 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1435
1436 /*Set wps station to configured*/
1437 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1438
1439 if(pIe)
1440 {
1441 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1442 {
1443 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1444 return -EINVAL;
1445 }
1446 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1447 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001448 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 /* Check 15 bit of WPS IE as it contain information for wps state
1450 * WPS state
1451 */
1452 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1453 {
1454 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1455 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1456 {
1457 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1458 }
1459 }
1460 }
1461 else
1462 {
1463 pConfig->wps_state = SAP_WPS_DISABLED;
1464 }
1465 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1466
1467 pConfig->RSNWPAReqIELength = 0;
1468 pConfig->pRSNWPAReqIE = NULL;
1469 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1470 WLAN_EID_RSN);
1471 if(pIe && pIe[1])
1472 {
1473 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1474 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1475 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1476 /* The actual processing may eventually be more extensive than
1477 * this. Right now, just consume any PMKIDs that are sent in
1478 * by the app.
1479 * */
1480 status = hdd_softap_unpackIE(
1481 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1482 &RSNEncryptType,
1483 &mcRSNEncryptType,
1484 &RSNAuthType,
1485 pConfig->pRSNWPAReqIE[1]+2,
1486 pConfig->pRSNWPAReqIE );
1487
1488 if( VOS_STATUS_SUCCESS == status )
1489 {
1490 /* Now copy over all the security attributes you have
1491 * parsed out
1492 * */
1493 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1494 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1495 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1496 = RSNEncryptType;
1497 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1498 "EncryptionType = %d mcEncryptionType = %d\n"),
1499 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1500 }
1501 }
1502
1503 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1504 pBeacon->tail, pBeacon->tail_len);
1505
1506 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1507 {
1508 if (pConfig->pRSNWPAReqIE)
1509 {
1510 /*Mixed mode WPA/WPA2*/
1511 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1512 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1513 }
1514 else
1515 {
1516 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1517 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1518 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1519 status = hdd_softap_unpackIE(
1520 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1521 &RSNEncryptType,
1522 &mcRSNEncryptType,
1523 &RSNAuthType,
1524 pConfig->pRSNWPAReqIE[1]+2,
1525 pConfig->pRSNWPAReqIE );
1526
1527 if( VOS_STATUS_SUCCESS == status )
1528 {
1529 /* Now copy over all the security attributes you have
1530 * parsed out
1531 * */
1532 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1533 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1534 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1535 = RSNEncryptType;
1536 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1537 "EncryptionType = %d mcEncryptionType = %d\n"),
1538 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1539 }
1540 }
1541 }
1542
1543 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1544
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001545#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 if (params->ssid != NULL)
1547 {
1548 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1549 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1550 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1551 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1552 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001553#else
1554 if (ssid != NULL)
1555 {
1556 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1557 pConfig->SSIDinfo.ssid.length = ssid_len;
1558 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1559 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1560 }
1561#endif
1562
Jeff Johnson295189b2012-06-20 16:38:30 -07001563 vos_mem_copy(pConfig->self_macaddr.bytes,
1564 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1565
1566 /* default value */
1567 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1568 pConfig->num_accept_mac = 0;
1569 pConfig->num_deny_mac = 0;
1570
1571 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1572 pBeacon->tail, pBeacon->tail_len);
1573
1574 /* pIe for black list is following form:
1575 type : 1 byte
1576 length : 1 byte
1577 OUI : 4 bytes
1578 acl type : 1 byte
1579 no of mac addr in black list: 1 byte
1580 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1581 */
1582 if ((pIe != NULL) && (pIe[1] != 0))
1583 {
1584 pConfig->SapMacaddr_acl = pIe[6];
1585 pConfig->num_deny_mac = pIe[7];
1586 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1587 pIe[6], pIe[7]);
1588 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1589 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1590 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1591 for (i = 0; i < pConfig->num_deny_mac; i++)
1592 {
1593 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1594 acl_entry++;
1595 }
1596 }
1597 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1598 pBeacon->tail, pBeacon->tail_len);
1599
1600 /* pIe for white list is following form:
1601 type : 1 byte
1602 length : 1 byte
1603 OUI : 4 bytes
1604 acl type : 1 byte
1605 no of mac addr in white list: 1 byte
1606 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1607 */
1608 if ((pIe != NULL) && (pIe[1] != 0))
1609 {
1610 pConfig->SapMacaddr_acl = pIe[6];
1611 pConfig->num_accept_mac = pIe[7];
1612 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1613 pIe[6], pIe[7]);
1614 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1615 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1616 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1617 for (i = 0; i < pConfig->num_accept_mac; i++)
1618 {
1619 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1620 acl_entry++;
1621 }
1622 }
1623 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1624
Jeff Johnsone7245742012-09-05 17:12:55 -07001625#ifdef WLAN_FEATURE_11AC
1626 if(((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1627 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1628 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) )
1629 {
1630 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1631 }
1632#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301633
1634 wlan_hdd_select_cbmode(pHostapdAdapter,pConfig);
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 // ht_capab is not what the name conveys,this is used for protection bitmap
1636 pConfig->ht_capab =
1637 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1638
1639 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1640 {
1641 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1642 return -EINVAL;
1643 }
1644
1645 //Uapsd Enabled Bit
1646 pConfig->UapsdEnable =
1647 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1648 //Enable OBSS protection
1649 pConfig->obssProtEnabled =
1650 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1651
1652 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1653 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1654 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1655 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1656 (int)pConfig->channel);
1657 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1658 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1659 pConfig->authType);
1660 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1661 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1662 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1663 pConfig->protEnabled, pConfig->obssProtEnabled);
1664
1665 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1666 {
1667 //Bss already started. just return.
1668 //TODO Probably it should update some beacon params.
1669 hddLog( LOGE, "Bss Already started...Ignore the request");
1670 EXIT();
1671 return 0;
1672 }
1673
1674 pConfig->persona = pHostapdAdapter->device_mode;
1675
1676 pSapEventCallback = hdd_hostapd_SAPEventCB;
1677 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1678 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1679 {
1680 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1681 return -EINVAL;
1682 }
1683
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001684 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001685 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1686
1687 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1688
1689 if (!VOS_IS_STATUS_SUCCESS(status))
1690 {
1691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 ("ERROR: HDD vos wait for single_event failed!!\n"));
1693 VOS_ASSERT(0);
1694 }
1695
1696 //Succesfully started Bss update the state bit.
1697 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1698
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001699#ifdef WLAN_FEATURE_P2P_DEBUG
1700 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1701 {
1702 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1703 {
1704 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1705 hddLog(LOGE,"[P2P State] From Go nego completed to "
1706 "Non-autonomus Group started");
1707 }
1708 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1709 {
1710 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1711 hddLog(LOGE,"[P2P State] From Inactive to "
1712 "Autonomus Group started");
1713 }
1714 }
1715#endif
1716
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 pHostapdState->bCommit = TRUE;
1718 EXIT();
1719
1720 return 0;
1721}
1722
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001723#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001724static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1725 struct net_device *dev,
1726 struct beacon_parameters *params)
1727{
1728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1729 int status=VOS_STATUS_SUCCESS;
1730
1731 ENTER();
1732
1733 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1734
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001735 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1736 {
1737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1738 "%s:LOGP in Progress. Ignore!!!", __func__);
1739 return -EAGAIN;
1740 }
1741
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1743#ifdef WLAN_FEATURE_P2P
1744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1745#endif
1746 )
1747 {
1748 beacon_data_t *old,*new;
1749
1750 old = pAdapter->sessionCtx.ap.beacon;
1751
1752 if (old)
1753 return -EALREADY;
1754
1755 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1756
1757 if(status != VOS_STATUS_SUCCESS)
1758 {
1759 hddLog(VOS_TRACE_LEVEL_FATAL,
1760 "%s:Error!!! Allocating the new beacon\n",__func__);
1761 return -EINVAL;
1762 }
1763
1764 pAdapter->sessionCtx.ap.beacon = new;
1765
1766 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1767 }
1768
1769 EXIT();
1770 return status;
1771}
1772
1773static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
1774 struct net_device *dev,
1775 struct beacon_parameters *params)
1776{
1777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1778 int status=VOS_STATUS_SUCCESS;
1779
1780 ENTER();
1781
1782 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1783 __func__,pAdapter->device_mode);
1784
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001785 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1786 {
1787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1788 "%s:LOGP in Progress. Ignore!!!", __func__);
1789 return -EAGAIN;
1790 }
1791
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1793#ifdef WLAN_FEATURE_P2P
1794 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1795#endif
1796 )
1797 {
1798 beacon_data_t *old,*new;
1799
1800 old = pAdapter->sessionCtx.ap.beacon;
1801
1802 if (!old)
1803 return -ENOENT;
1804
1805 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1806
1807 if(status != VOS_STATUS_SUCCESS) {
1808 hddLog(VOS_TRACE_LEVEL_FATAL,
1809 "%s: Error!!! Allocating the new beacon\n",__func__);
1810 return -EINVAL;
1811 }
1812
1813 pAdapter->sessionCtx.ap.beacon = new;
1814
1815 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1816 }
1817
1818 EXIT();
1819 return status;
1820}
1821
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001822#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1823
1824#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001825static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
1826 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001827#else
1828static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
1829 struct net_device *dev)
1830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001831{
1832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001833 hdd_context_t *pHddCtx = NULL;
1834 hdd_scaninfo_t *pScanInfo = NULL;
1835 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 VOS_STATUS status = 0;
1837
1838 ENTER();
1839
1840 if (NULL == pAdapter)
1841 {
1842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001843 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 return -ENODEV;
1845 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001846 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1847 {
1848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "%s:LOGP in Progress. Ignore!!!", __func__);
1850 return -EAGAIN;
1851 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001852
1853 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1854 if (NULL == pHddCtx)
1855 {
1856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001857 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001858 return -ENODEV;
1859 }
1860
1861 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
1862 if (NULL == staAdapter)
1863 {
1864 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
1865 if (NULL == staAdapter)
1866 {
1867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001868 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001869 return -ENODEV;
1870 }
1871 }
1872
1873 pScanInfo = &pHddCtx->scan_info;
1874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1876 {
1877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1878 return -EAGAIN;
1879 }
1880
1881 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1882
1883 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1884 __func__,pAdapter->device_mode);
1885
Jeff Johnsone7245742012-09-05 17:12:55 -07001886 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
1887 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001888 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07001889 hdd_abort_mac_scan(staAdapter->pHddCtx);
1890 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001891 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07001892 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
1893 if (!status)
1894 {
1895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1896 "%s: Timeout occured while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001897 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001898 VOS_ASSERT(pScanInfo->mScanPending);
1899 return 0;
1900 }
1901 }
1902
Jeff Johnson295189b2012-06-20 16:38:30 -07001903 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1904#ifdef WLAN_FEATURE_P2P
1905 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1906#endif
1907 )
1908 {
1909 beacon_data_t *old;
1910
1911 old = pAdapter->sessionCtx.ap.beacon;
1912
1913 if (!old)
1914 return -ENOENT;
1915
1916#ifdef CONFIG_CFG80211
1917 hdd_cleanup_actionframe(pHddCtx, pAdapter);
1918#endif
1919
1920 mutex_lock(&pHddCtx->sap_lock);
1921 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
1922 {
1923 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
1924 {
1925 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1926
1927 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1928
1929 if (!VOS_IS_STATUS_SUCCESS(status))
1930 {
1931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1932 ("ERROR: HDD vos wait for single_event failed!!\n"));
1933 VOS_ASSERT(0);
1934 }
1935 }
1936 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
1937 }
1938 mutex_unlock(&pHddCtx->sap_lock);
1939
1940 if(status != VOS_STATUS_SUCCESS)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_FATAL,
1943 "%s:Error!!! Stopping the BSS\n",__func__);
1944 return -EINVAL;
1945 }
1946
1947 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1948 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
1949 ==eHAL_STATUS_FAILURE)
1950 {
1951 hddLog(LOGE,
1952 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
1953 }
1954
1955 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
1956 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1957 eANI_BOOLEAN_FALSE) )
1958 {
1959 hddLog(LOGE,
1960 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1961 }
1962
1963 // Reset WNI_CFG_PROBE_RSP Flags
1964 wlan_hdd_reset_prob_rspies(pAdapter);
1965
1966 pAdapter->sessionCtx.ap.beacon = NULL;
1967 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001968#ifdef WLAN_FEATURE_P2P_DEBUG
1969 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
1970 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
1971 {
1972 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
1973 "GO got removed");
1974 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
1975 }
1976#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 }
1978 EXIT();
1979 return status;
1980}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001981
1982#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
1983
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05301984static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
1985 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001986 struct cfg80211_ap_settings *params)
1987{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05301988 hdd_adapter_t *pAdapter;
1989 hdd_context_t *pHddCtx;
1990 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001991
1992 ENTER();
1993
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05301994 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001995 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05301996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1997 "%s: Device is Null", __func__);
1998 return -ENODEV;
1999 }
2000
2001 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2002 if (NULL == pAdapter)
2003 {
2004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2005 "%s: HDD adapter is Null", __func__);
2006 return -ENODEV;
2007 }
2008
2009 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2010 {
2011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2012 "%s: HDD adapter magic is invalid", __func__);
2013 return -ENODEV;
2014 }
2015
2016 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2017 if (NULL == pHddCtx)
2018 {
2019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2020 "%s: HDD context is Null", __func__);
2021 return -ENODEV;
2022 }
2023
2024 if (pHddCtx->isLogpInProgress)
2025 {
2026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2027 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002028 return -EAGAIN;
2029 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302030
2031 if (pHddCtx->isLoadUnloadInProgress)
2032 {
2033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2034 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2035 return -EAGAIN;
2036 }
2037
2038 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2039 __func__, pAdapter->device_mode);
2040
2041 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002042#ifdef WLAN_FEATURE_P2P
2043 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2044#endif
2045 )
2046 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302047 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002048
2049 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302050
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002051 if (old)
2052 return -EALREADY;
2053
2054 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2055
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302056 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002057 {
2058 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302059 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002060 return -EINVAL;
2061 }
2062 pAdapter->sessionCtx.ap.beacon = new;
2063 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2064 params->ssid_len, params->hidden_ssid);
2065 }
2066
2067 EXIT();
2068 return status;
2069}
2070
2071
2072static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2073 struct net_device *dev,
2074 struct cfg80211_beacon_data *params)
2075{
2076 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2077 int status=VOS_STATUS_SUCCESS;
2078
2079 ENTER();
2080
2081 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2082 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002083 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2084 {
2085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2086 return -EAGAIN;
2087 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002088
2089 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2090#ifdef WLAN_FEATURE_P2P
2091 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2092#endif
2093 )
2094 {
2095 beacon_data_t *old,*new;
2096
2097 old = pAdapter->sessionCtx.ap.beacon;
2098
2099 if (!old)
2100 return -ENOENT;
2101
2102 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2103
2104 if(status != VOS_STATUS_SUCCESS) {
2105 hddLog(VOS_TRACE_LEVEL_FATAL,
2106 "%s: Error!!! Allocating the new beacon\n",__func__);
2107 return -EINVAL;
2108 }
2109
2110 pAdapter->sessionCtx.ap.beacon = new;
2111
2112 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2113 }
2114
2115 EXIT();
2116 return status;
2117}
2118
2119#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2120
Jeff Johnson295189b2012-06-20 16:38:30 -07002121
2122static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2123 struct net_device *dev,
2124 struct bss_parameters *params)
2125{
2126 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2127
2128 ENTER();
2129
2130 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2131 __func__,pAdapter->device_mode);
2132
2133 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2134#ifdef WLAN_FEATURE_P2P
2135 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2136#endif
2137 )
2138 {
2139 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2140 * want to update this parameter */
2141 if (-1 != params->ap_isolate)
2142 {
2143 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2144 }
2145 }
2146
2147 EXIT();
2148 return 0;
2149}
2150
2151/*
2152 * FUNCTION: wlan_hdd_cfg80211_change_iface
2153 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2154 */
2155int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2156 struct net_device *ndev,
2157 enum nl80211_iftype type,
2158 u32 *flags,
2159 struct vif_params *params
2160 )
2161{
2162 struct wireless_dev *wdev;
2163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2164 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002165 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 tCsrRoamProfile *pRoamProfile = NULL;
2167 eCsrRoamBssType LastBSSType;
2168 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2169 eMib_dot11DesiredBssType connectedBssType;
2170 VOS_STATUS status;
2171
2172 ENTER();
2173
2174 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2175 {
2176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2177 return -EAGAIN;
2178 }
2179
2180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2181 __func__, pAdapter->device_mode);
2182
2183 wdev = ndev->ieee80211_ptr;
2184
2185#ifdef WLAN_BTAMP_FEATURE
2186 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2187 (NL80211_IFTYPE_ADHOC == type)||
2188 (NL80211_IFTYPE_AP == type)||
2189 (NL80211_IFTYPE_P2P_GO == type))
2190 {
2191 pHddCtx->isAmpAllowed = VOS_FALSE;
2192 // stop AMP traffic
2193 status = WLANBAP_StopAmp();
2194 if(VOS_STATUS_SUCCESS != status )
2195 {
2196 pHddCtx->isAmpAllowed = VOS_TRUE;
2197 hddLog(VOS_TRACE_LEVEL_FATAL,
2198 "%s: Failed to stop AMP", __func__);
2199 return -EINVAL;
2200 }
2201 }
2202#endif //WLAN_BTAMP_FEATURE
2203 /* Reset the current device mode bit mask*/
2204 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2205
2206 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2207#ifdef WLAN_FEATURE_P2P
2208 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002209 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002210#endif
2211 )
2212 {
2213 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2214 pRoamProfile = &pWextState->roamProfile;
2215 LastBSSType = pRoamProfile->BSSType;
2216
2217 switch (type)
2218 {
2219 case NL80211_IFTYPE_STATION:
2220#ifdef WLAN_FEATURE_P2P
2221 case NL80211_IFTYPE_P2P_CLIENT:
2222#endif
2223 hddLog(VOS_TRACE_LEVEL_INFO,
2224 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2225 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002226#ifdef WLAN_FEATURE_11AC
2227 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2228 {
2229 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2230 }
2231#endif
2232 pRoamProfile->phyMode =
2233 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002234 wdev->iftype = type;
2235#ifdef WLAN_FEATURE_P2P
2236 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2237 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
2238#endif
2239 break;
2240 case NL80211_IFTYPE_ADHOC:
2241 hddLog(VOS_TRACE_LEVEL_INFO,
2242 "%s: setting interface Type to ADHOC", __func__);
2243 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2244 pRoamProfile->phyMode =
2245 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2246 wdev->iftype = type;
2247 break;
2248
2249 case NL80211_IFTYPE_AP:
2250#ifdef WLAN_FEATURE_P2P
2251 case NL80211_IFTYPE_P2P_GO:
2252#endif
2253 {
2254 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2255 "%s: setting interface Type to %s", __func__,
2256 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2257
Mohit Khanna0f232092012-09-11 14:46:08 -07002258 if (NL80211_IFTYPE_AP == type)
2259 {
2260 /* As Loading WLAN Driver one interface being created for p2p device
2261 * address. This will take one HW STA and the max number of clients
2262 * that can connect to softAP will be reduced by one. so while changing
2263 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2264 * interface as it is not required in SoftAP mode.
2265 */
2266
2267 // Get P2P Adapter
2268 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2269
2270 if (pP2pAdapter)
2271 {
2272 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2273 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2274 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2275 }
2276 }
2277
Jeff Johnson295189b2012-06-20 16:38:30 -07002278 //De-init the adapter.
2279 hdd_stop_adapter( pHddCtx, pAdapter );
2280 hdd_deinit_adapter( pHddCtx, pAdapter );
2281 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2282#ifdef WLAN_SOFTAP_FEATURE
2283#ifdef WLAN_FEATURE_P2P
2284 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2285 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2286#else
2287 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2288#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002289
2290 //Disable BMPS and IMPS if enabled
2291 //before starting Go
2292 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2293 {
2294 if(VOS_STATUS_E_FAILURE ==
2295 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2296 {
2297 //Fail to Exit BMPS
2298 VOS_ASSERT(0);
2299 }
2300 }
2301
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002302 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2303 (pConfig->apRandomBssidEnabled))
2304 {
2305 /* To meet Android requirements create a randomized
2306 MAC address of the form 02:1A:11:Fx:xx:xx */
2307 get_random_bytes(&ndev->dev_addr[3], 3);
2308 ndev->dev_addr[0] = 0x02;
2309 ndev->dev_addr[1] = 0x1A;
2310 ndev->dev_addr[2] = 0x11;
2311 ndev->dev_addr[3] |= 0xF0;
2312 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2313 VOS_MAC_ADDR_SIZE);
2314 pr_info("wlan: Generated HotSpot BSSID "
2315 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2316 ndev->dev_addr[0],
2317 ndev->dev_addr[1],
2318 ndev->dev_addr[2],
2319 ndev->dev_addr[3],
2320 ndev->dev_addr[4],
2321 ndev->dev_addr[5]);
2322 }
2323
Jeff Johnson295189b2012-06-20 16:38:30 -07002324 hdd_set_ap_ops( pAdapter->dev );
2325
2326 status = hdd_init_ap_mode(pAdapter);
2327 if(status != VOS_STATUS_SUCCESS)
2328 {
2329 hddLog(VOS_TRACE_LEVEL_FATAL,
2330 "%s: Error initializing the ap mode", __func__);
2331 return -EINVAL;
2332 }
2333 hdd_set_conparam(1);
2334
2335#endif
2336 /*interface type changed update in wiphy structure*/
2337 if(wdev)
2338 {
2339 wdev->iftype = type;
2340 pHddCtx->change_iface = type;
2341 }
2342 else
2343 {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2346 return -EINVAL;
2347 }
2348 goto done;
2349 }
2350
2351 default:
2352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2353 __func__);
2354 return -EOPNOTSUPP;
2355 }
2356 }
2357 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2358#ifdef WLAN_FEATURE_P2P
2359 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2360#endif
2361 )
2362 {
2363 switch(type)
2364 {
2365 case NL80211_IFTYPE_STATION:
2366#ifdef WLAN_FEATURE_P2P
2367 case NL80211_IFTYPE_P2P_CLIENT:
2368#endif
2369 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002370 hdd_stop_adapter( pHddCtx, pAdapter );
2371 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 wdev->iftype = type;
2373#ifdef WLAN_FEATURE_P2P
2374 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2375 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
2376#endif
2377 hdd_set_conparam(0);
2378 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2380 hdd_set_station_ops( pAdapter->dev );
2381 status = hdd_init_station_mode( pAdapter );
2382 if( VOS_STATUS_SUCCESS != status )
2383 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002384 /* In case of JB, for P2P-GO, only change interface will be called,
2385 * This is the right place to enable back bmps_imps()
2386 */
2387 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002388 goto done;
2389 case NL80211_IFTYPE_AP:
2390#ifdef WLAN_FEATURE_P2P
2391 case NL80211_IFTYPE_P2P_GO:
2392#endif
2393 wdev->iftype = type;
2394#ifdef WLAN_FEATURE_P2P
2395 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2396 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2397#endif
2398 goto done;
2399 default:
2400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2401 __func__);
2402 return -EOPNOTSUPP;
2403
2404 }
2405
2406 }
2407 else
2408 {
2409 return -EOPNOTSUPP;
2410 }
2411
2412
2413 if(pRoamProfile)
2414 {
2415 if ( LastBSSType != pRoamProfile->BSSType )
2416 {
2417 /*interface type changed update in wiphy structure*/
2418 wdev->iftype = type;
2419
2420 /*the BSS mode changed, We need to issue disconnect
2421 if connected or in IBSS disconnect state*/
2422 if ( hdd_connGetConnectedBssType(
2423 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2424 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2425 {
2426 /*need to issue a disconnect to CSR.*/
2427 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2428 if( eHAL_STATUS_SUCCESS ==
2429 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2430 pAdapter->sessionId,
2431 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2432 {
2433 wait_for_completion_interruptible_timeout(
2434 &pAdapter->disconnect_comp_var,
2435 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2436 }
2437 }
2438 }
2439 }
2440
2441done:
2442 /*set bitmask based on updated value*/
2443 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2444#ifdef WLAN_BTAMP_FEATURE
2445 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2446 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2447 {
2448 //we are ok to do AMP
2449 pHddCtx->isAmpAllowed = VOS_TRUE;
2450 }
2451#endif //WLAN_BTAMP_FEATURE
2452 EXIT();
2453 return 0;
2454}
2455
2456static int wlan_hdd_change_station(struct wiphy *wiphy,
2457 struct net_device *dev,
2458 u8 *mac,
2459 struct station_parameters *params)
2460{
2461 VOS_STATUS status = VOS_STATUS_SUCCESS;
2462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2463 v_MACADDR_t STAMacAddress;
2464
Jeff Johnsone7245742012-09-05 17:12:55 -07002465 ENTER();
2466
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002467 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2468 {
2469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2470 "%s:LOGP in Progress. Ignore!!!", __func__);
2471 return -EAGAIN;
2472 }
2473
Jeff Johnson295189b2012-06-20 16:38:30 -07002474 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2475
2476 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2477#ifdef WLAN_FEATURE_P2P
2478 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2479#endif
2480 )
2481 {
2482 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2483 {
2484 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2485 WLANTL_STA_AUTHENTICATED);
2486
2487 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002488 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002489 return -EINVAL;
2490 }
2491 }
2492
Jeff Johnsone7245742012-09-05 17:12:55 -07002493 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002494 return status;
2495}
2496
2497/*
2498 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2499 * This function is used to get peer station index in IBSS mode
2500 */
2501static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2502{
2503 u8 idx = 0;
2504 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2505 ENTER();
2506 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2507 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2508 {
2509 if ( (0 !=
2510 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2511 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2512 temp, VOS_MAC_ADDR_SIZE)
2513 )
2514 {
2515 return idx;
2516 }
2517 }
2518 return idx;
2519}
2520
2521
2522/*
2523 * FUNCTION: wlan_hdd_cfg80211_add_key
2524 * This function is used to initialize the key information
2525 */
2526#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2527static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2528 struct net_device *ndev,
2529 u8 key_index, bool pairwise,
2530 const u8 *mac_addr,
2531 struct key_params *params
2532 )
2533#else
2534static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2535 struct net_device *ndev,
2536 u8 key_index, const u8 *mac_addr,
2537 struct key_params *params
2538 )
2539#endif
2540{
2541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2542 tCsrRoamSetKey setKey;
2543 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2544 int status = 0;
2545 v_U32_t roamId= 0xFF;
2546 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2547 hdd_hostapd_state_t *pHostapdState;
2548 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002549 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002550
2551 ENTER();
2552
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002553 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2554 {
2555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2556 "%s:LOGP in Progress. Ignore!!!", __func__);
2557 return -EAGAIN;
2558 }
2559
Jeff Johnson295189b2012-06-20 16:38:30 -07002560 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2561 __func__,pAdapter->device_mode);
2562
2563 if (CSR_MAX_NUM_KEY <= key_index)
2564 {
2565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2566 key_index);
2567
2568 return -EINVAL;
2569 }
2570
2571 hddLog(VOS_TRACE_LEVEL_INFO,
2572 "%s: called with key index = %d & key length %d",
2573 __func__, key_index, params->key_len);
2574
2575 /*extract key idx, key len and key*/
2576 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2577 setKey.keyId = key_index;
2578 setKey.keyLength = params->key_len;
2579 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2580
2581 switch (params->cipher)
2582 {
2583 case WLAN_CIPHER_SUITE_WEP40:
2584 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2585 break;
2586
2587 case WLAN_CIPHER_SUITE_WEP104:
2588 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2589 break;
2590
2591 case WLAN_CIPHER_SUITE_TKIP:
2592 {
2593 u8 *pKey = &setKey.Key[0];
2594 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2595
2596 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2597
2598 /*Supplicant sends the 32bytes key in this order
2599
2600 |--------------|----------|----------|
2601 | Tk1 |TX-MIC | RX Mic |
2602 |--------------|----------|----------|
2603 <---16bytes---><--8bytes--><--8bytes-->
2604
2605 */
2606 /*Sme expects the 32 bytes key to be in the below order
2607
2608 |--------------|----------|----------|
2609 | Tk1 |RX-MIC | TX Mic |
2610 |--------------|----------|----------|
2611 <---16bytes---><--8bytes--><--8bytes-->
2612 */
2613 /* Copy the Temporal Key 1 (TK1) */
2614 vos_mem_copy(pKey, params->key,16);
2615
2616 /*Copy the rx mic first*/
2617 vos_mem_copy(&pKey[16],&params->key[24],8);
2618
2619 /*Copy the tx mic */
2620 vos_mem_copy(&pKey[24],&params->key[16],8);
2621
2622
2623 break;
2624 }
2625
2626 case WLAN_CIPHER_SUITE_CCMP:
2627 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2628 break;
2629
2630#ifdef FEATURE_WLAN_WAPI
2631 case WLAN_CIPHER_SUITE_SMS4:
2632 {
2633 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2634 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2635 params->key, params->key_len);
2636 return 0;
2637 }
2638#endif
2639#ifdef FEATURE_WLAN_CCX
2640 case WLAN_CIPHER_SUITE_KRK:
2641 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2642 break;
2643#endif
2644 default:
2645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2646 __func__, params->cipher);
2647 return -EOPNOTSUPP;
2648 }
2649
2650 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2651 __func__, setKey.encType);
2652
2653
2654
2655 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2656#ifdef WLAN_FEATURE_P2P
2657 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2658#endif
2659 )
2660 {
2661
2662
2663 if (
2664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2665 (!pairwise)
2666#else
2667 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2668#endif
2669 )
2670 {
2671 /* set group key*/
2672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2673 "%s- %d: setting Broacast key",
2674 __func__, __LINE__);
2675 setKey.keyDirection = eSIR_RX_ONLY;
2676 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2677 }
2678 else
2679 {
2680 /* set pairwise key*/
2681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2682 "%s- %d: setting pairwise key",
2683 __func__, __LINE__);
2684 setKey.keyDirection = eSIR_TX_RX;
2685 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2686 }
2687
2688 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2689 if( pHostapdState->bssState == BSS_START )
2690 {
2691 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2692
2693 if ( status != eHAL_STATUS_SUCCESS )
2694 {
2695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2696 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2697 __LINE__, status );
2698 }
2699 }
2700
2701 /* Saving WEP keys */
2702 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2703 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2704 {
2705 //Save the wep 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->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2708 }
2709 else
2710 {
2711 //Save the key in ap context. Issue setkey after the BSS is started.
2712 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2713 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2714 }
2715 }
2716 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2717#ifdef WLAN_FEATURE_P2P
2718 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2719#endif
2720 )
2721 {
2722 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2723 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2724
2725 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
2726
2727 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
2728 params->key, params->key_len);
2729
2730 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2731
2732 if (!( ( IW_AUTH_KEY_MGMT_802_1X
2733 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2734 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2735 )
2736 &&
2737 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2738 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2739 )
2740 )
2741 {
2742 /* in case of static WEP, macaddr/bssid is not coming from nl80211
2743 * interface, copy bssid for pairwise key and group macaddr for
2744 * group key initialization*/
2745
2746 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2747
2748 pWextState->roamProfile.negotiatedUCEncryptionType =
2749 pHddStaCtx->conn_info.ucEncryptionType =
2750 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
2751 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
2752 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
2753
2754
2755 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2756 "%s: Negotiated encryption type %d", __func__,
2757 pWextState->roamProfile.negotiatedUCEncryptionType);
2758
2759 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
2760 &pWextState->roamProfile, true);
2761 setKey.keyLength = 0;
2762 setKey.keyDirection = eSIR_TX_RX;
2763
2764#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2765 if (pairwise)
2766 {
2767#endif
2768 if (mac_addr)
2769 {
2770 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2771 }
2772 else
2773 {
2774 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
2775 * and peerMacAddress in case of IBSS*/
2776 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
2777 {
2778 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
2779 if (HDD_MAX_NUM_IBSS_STA != staidx)
2780 {
2781 vos_mem_copy(setKey.peerMac,
2782 &pHddStaCtx->conn_info.peerMacAddress[staidx],
2783 WNI_CFG_BSSID_LEN);
2784
2785 }
2786 else
2787 {
2788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
2789 __func__);
2790 return -EOPNOTSUPP;
2791 }
2792 }
2793 else
2794 {
2795 vos_mem_copy(setKey.peerMac,
2796 &pHddStaCtx->conn_info.bssId[0],
2797 WNI_CFG_BSSID_LEN);
2798 }
2799 }
2800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2801 }
2802 else
2803 {
2804 /* set group key*/
2805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2806 "%s- %d: setting Group key",
2807 __func__, __LINE__);
2808 setKey.keyDirection = eSIR_RX_ONLY;
2809 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2810 }
2811#endif
2812 }
2813 else if (
2814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2815 (!pairwise)
2816#else
2817 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2818#endif
2819 )
2820 {
2821 /* set group key*/
2822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2823 "%s- %d: setting Group key",
2824 __func__, __LINE__);
2825 setKey.keyDirection = eSIR_RX_ONLY;
2826 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2827 }
2828 else
2829 {
2830 /* set pairwise key*/
2831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2832 "%s- %d: setting pairwise key",
2833 __func__, __LINE__);
2834 setKey.keyDirection = eSIR_TX_RX;
2835 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2836 }
2837
2838 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2839 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2840 __func__, setKey.peerMac[0], setKey.peerMac[1],
2841 setKey.peerMac[2], setKey.peerMac[3],
2842 setKey.peerMac[4], setKey.peerMac[5],
2843 setKey.keyDirection);
2844
2845 vos_status = wlan_hdd_check_ula_done(pAdapter);
2846
2847 if ( vos_status != VOS_STATUS_SUCCESS )
2848 {
2849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2850 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
2851 __LINE__, vos_status );
2852
2853 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2854
2855 return -EINVAL;
2856
2857 }
2858
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002859#ifdef WLAN_FEATURE_VOWIFI_11R
2860 /* The supplicant may attempt to set the PTK once pre-authentication is done.
2861 Save the key in the UMAC and include it in the ADD BSS request */
2862 /*TODO 11r - is this used?? */
2863 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
2864 if( halStatus == eHAL_STATUS_SUCCESS )
2865 {
2866 return halStatus;
2867 }
2868#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07002869
2870 /* issue set key request to SME*/
2871 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2872 pAdapter->sessionId, &setKey, &roamId );
2873
2874 if ( 0 != status )
2875 {
2876 hddLog(VOS_TRACE_LEVEL_ERROR,
2877 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
2878 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2879 return -EINVAL;
2880 }
2881
2882
2883 /* in case of IBSS as there was no information available about WEP keys during
2884 * IBSS join, group key intialized with NULL key, so re-initialize group key
2885 * with correct value*/
2886 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
2887 !( ( IW_AUTH_KEY_MGMT_802_1X
2888 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2889 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2890 )
2891 &&
2892 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2893 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2894 )
2895 )
2896 {
2897 setKey.keyDirection = eSIR_RX_ONLY;
2898 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2899
2900 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2901 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2902 __func__, setKey.peerMac[0], setKey.peerMac[1],
2903 setKey.peerMac[2], setKey.peerMac[3],
2904 setKey.peerMac[4], setKey.peerMac[5],
2905 setKey.keyDirection);
2906
2907 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
2908 pAdapter->sessionId, &setKey, &roamId );
2909
2910 if ( 0 != status )
2911 {
2912 hddLog(VOS_TRACE_LEVEL_ERROR,
2913 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
2914 __func__, status);
2915 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2916 return -EINVAL;
2917 }
2918 }
2919 }
2920
2921 return 0;
2922}
2923
2924/*
2925 * FUNCTION: wlan_hdd_cfg80211_get_key
2926 * This function is used to get the key information
2927 */
2928#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2929static int wlan_hdd_cfg80211_get_key(
2930 struct wiphy *wiphy,
2931 struct net_device *ndev,
2932 u8 key_index, bool pairwise,
2933 const u8 *mac_addr, void *cookie,
2934 void (*callback)(void *cookie, struct key_params*)
2935 )
2936#else
2937static int wlan_hdd_cfg80211_get_key(
2938 struct wiphy *wiphy,
2939 struct net_device *ndev,
2940 u8 key_index, const u8 *mac_addr, void *cookie,
2941 void (*callback)(void *cookie, struct key_params*)
2942 )
2943#endif
2944{
2945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2946 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2947 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2948 struct key_params params;
2949
2950 ENTER();
2951
2952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2953 __func__,pAdapter->device_mode);
2954
2955 memset(&params, 0, sizeof(params));
2956
2957 if (CSR_MAX_NUM_KEY <= key_index)
2958 {
2959 return -EINVAL;
2960 }
2961
2962 switch(pRoamProfile->EncryptionType.encryptionType[0])
2963 {
2964 case eCSR_ENCRYPT_TYPE_NONE:
2965 params.cipher = IW_AUTH_CIPHER_NONE;
2966 break;
2967
2968 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2969 case eCSR_ENCRYPT_TYPE_WEP40:
2970 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2971 break;
2972
2973 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2974 case eCSR_ENCRYPT_TYPE_WEP104:
2975 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2976 break;
2977
2978 case eCSR_ENCRYPT_TYPE_TKIP:
2979 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2980 break;
2981
2982 case eCSR_ENCRYPT_TYPE_AES:
2983 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2984 break;
2985
2986 default:
2987 params.cipher = IW_AUTH_CIPHER_NONE;
2988 break;
2989 }
2990
2991 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
2992 params.seq_len = 0;
2993 params.seq = NULL;
2994 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
2995 callback(cookie, &params);
2996 return 0;
2997}
2998
2999/*
3000 * FUNCTION: wlan_hdd_cfg80211_del_key
3001 * This function is used to delete the key information
3002 */
3003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3004static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3005 struct net_device *ndev,
3006 u8 key_index,
3007 bool pairwise,
3008 const u8 *mac_addr
3009 )
3010#else
3011static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3012 struct net_device *ndev,
3013 u8 key_index,
3014 const u8 *mac_addr
3015 )
3016#endif
3017{
3018 int status = 0;
3019
3020 //This code needs to be revisited. There is sme_removeKey API, we should
3021 //plan to use that. After the change to use correct index in setkey,
3022 //it is observed that this is invalidating peer
3023 //key index whenever re-key is done. This is affecting data link.
3024 //It should be ok to ignore del_key.
3025#if 0
3026 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3027 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3028 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3029 tCsrRoamSetKey setKey;
3030 v_U32_t roamId= 0xFF;
3031
3032 ENTER();
3033
3034 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3035 __func__,pAdapter->device_mode);
3036
3037 if (CSR_MAX_NUM_KEY <= key_index)
3038 {
3039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3040 key_index);
3041
3042 return -EINVAL;
3043 }
3044
3045 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3046 setKey.keyId = key_index;
3047
3048 if (mac_addr)
3049 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3050 else
3051 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3052
3053 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3054
3055 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3056#ifdef WLAN_FEATURE_P2P
3057 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3058#endif
3059 )
3060 {
3061
3062 hdd_hostapd_state_t *pHostapdState =
3063 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3064 if( pHostapdState->bssState == BSS_START)
3065 {
3066 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3067
3068 if ( status != eHAL_STATUS_SUCCESS )
3069 {
3070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3071 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3072 __LINE__, status );
3073 }
3074 }
3075 }
3076 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3077#ifdef WLAN_FEATURE_P2P
3078 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3079#endif
3080 )
3081 {
3082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3083
3084 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3085
3086 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3087 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3088 __func__, setKey.peerMac[0], setKey.peerMac[1],
3089 setKey.peerMac[2], setKey.peerMac[3],
3090 setKey.peerMac[4], setKey.peerMac[5]);
3091 if(pAdapter->sessionCtx.station.conn_info.connState ==
3092 eConnectionState_Associated)
3093 {
3094 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3095 pAdapter->sessionId, &setKey, &roamId );
3096
3097 if ( 0 != status )
3098 {
3099 hddLog(VOS_TRACE_LEVEL_ERROR,
3100 "%s: sme_RoamSetKey failure, returned %d",
3101 __func__, status);
3102 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3103 return -EINVAL;
3104 }
3105 }
3106 }
3107#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003108 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 return status;
3110}
3111
3112/*
3113 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3114 * This function is used to set the default tx key index
3115 */
3116#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3117static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3118 struct net_device *ndev,
3119 u8 key_index,
3120 bool unicast, bool multicast)
3121#else
3122static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3123 struct net_device *ndev,
3124 u8 key_index)
3125#endif
3126{
3127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3128 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3129 int status = 0;
3130 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3131
3132 ENTER();
3133
3134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3135 __func__,pAdapter->device_mode, key_index);
3136
3137 if (CSR_MAX_NUM_KEY <= key_index)
3138 {
3139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3140 key_index);
3141
3142 return -EINVAL;
3143 }
3144
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003145 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3146 {
3147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3148 "%s:LOGP in Progress. Ignore!!!", __func__);
3149 return -EAGAIN;
3150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003151
3152 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3153#ifdef WLAN_FEATURE_P2P
3154 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3155#endif
3156 )
3157 {
3158 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3159 (eCSR_ENCRYPT_TYPE_TKIP !=
3160 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3161 (eCSR_ENCRYPT_TYPE_AES !=
3162 pWextState->roamProfile.EncryptionType.encryptionType[0])
3163 )
3164 {
3165 /* if default key index is not same as previous one,
3166 * then update the default key index */
3167
3168 tCsrRoamSetKey setKey;
3169 v_U32_t roamId= 0xFF;
3170 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3171
3172 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3173 __func__, key_index);
3174
3175 Keys->defaultIndex = (u8)key_index;
3176 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3177 setKey.keyId = key_index;
3178 setKey.keyLength = Keys->KeyLength[key_index];
3179
3180 vos_mem_copy(&setKey.Key[0],
3181 &Keys->KeyMaterial[key_index][0],
3182 Keys->KeyLength[key_index]);
3183
3184 setKey.keyDirection = eSIR_TX_ONLY;
3185
3186 vos_mem_copy(setKey.peerMac,
3187 &pHddStaCtx->conn_info.bssId[0],
3188 WNI_CFG_BSSID_LEN);
3189
3190 setKey.encType =
3191 pWextState->roamProfile.EncryptionType.encryptionType[0];
3192
3193 /* issue set key request */
3194 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3195 pAdapter->sessionId, &setKey, &roamId );
3196
3197 if ( 0 != status )
3198 {
3199 hddLog(VOS_TRACE_LEVEL_ERROR,
3200 "%s: sme_RoamSetKey failed, returned %d", __func__,
3201 status);
3202 return -EINVAL;
3203 }
3204 }
3205 }
3206
3207 /* In SoftAp mode setting key direction for default mode */
3208 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3209 {
3210 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3211 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3212 (eCSR_ENCRYPT_TYPE_AES !=
3213 pWextState->roamProfile.EncryptionType.encryptionType[0])
3214 )
3215 {
3216 /* Saving key direction for default key index to TX default */
3217 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3218 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3219 }
3220 }
3221
3222 return status;
3223}
3224
3225/**
3226 * FUNCTION: wlan_hdd_cfg80211_set_channel
3227 * This function is used to set the channel number
3228 */
3229int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
3230 struct ieee80211_channel *chan,
3231 enum nl80211_channel_type channel_type
3232 )
3233{
3234 v_U32_t num_ch = 0;
3235 u32 channel = 0;
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003236 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003237 int freq = chan->center_freq; /* freq is in MHZ */
3238
3239 ENTER();
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003240
3241 if( NULL == dev )
3242 {
3243 hddLog(VOS_TRACE_LEVEL_ERROR,
3244 "%s: Called with dev = NULL.\n", __func__);
3245 return -ENODEV;
3246 }
3247 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003248
3249 hddLog(VOS_TRACE_LEVEL_INFO,
3250 "%s: device_mode = %d freq = %d \n",__func__,
3251 pAdapter->device_mode, chan->center_freq);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07003252 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3253 {
3254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3255 return -EAGAIN;
3256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003257
3258 /*
3259 * Do freq to chan conversion
3260 * TODO: for 11a
3261 */
3262
3263 channel = ieee80211_frequency_to_channel(freq);
3264
3265 /* Check freq range */
3266 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3267 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
3268 {
3269 hddLog(VOS_TRACE_LEVEL_ERROR,
3270 "%s: Channel [%d] is outside valid range from %d to %d\n",
3271 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3272 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3273 return -EINVAL;
3274 }
3275
3276 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3277
3278 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
3279#ifdef WLAN_FEATURE_P2P
3280 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
3281#endif
3282 )
3283 {
3284 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
3285 {
3286 hddLog(VOS_TRACE_LEVEL_ERROR,
3287 "%s: Invalid Channel [%d] \n", __func__, channel);
3288 return -EINVAL;
3289 }
3290 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3291 "%s: set channel to [%d] for device mode =%d",
3292 __func__, channel,pAdapter->device_mode);
3293 }
3294 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3295#ifdef WLAN_FEATURE_P2P
3296 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3297#endif
3298 )
3299 {
3300 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3301 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
3302 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3303
3304 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
3305 {
3306 /* Link is up then return cant set channel*/
3307 hddLog( VOS_TRACE_LEVEL_ERROR,
3308 "%s: IBSS Associated, can't set the channel\n", __func__);
3309 return -EINVAL;
3310 }
3311
3312 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
3313 pHddStaCtx->conn_info.operationChannel = channel;
3314 pRoamProfile->ChannelInfo.ChannelList =
3315 &pHddStaCtx->conn_info.operationChannel;
3316 }
3317 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3318#ifdef WLAN_FEATURE_P2P
3319 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3320#endif
3321 )
3322 {
3323 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
3324
3325 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3326 {
3327 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3328
3329 /* If auto channel selection is configured as enable/ 1 then ignore
3330 channel set by supplicant
3331 */
3332 if ( cfg_param->apAutoChannelSelection )
3333 {
3334 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
3335
3336 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3337 "%s: set channel to auto channel (0) for device mode =%d",
3338 __func__, pAdapter->device_mode);
3339 }
3340 }
3341 }
3342 else
3343 {
3344 hddLog(VOS_TRACE_LEVEL_FATAL,
3345 "%s: Invalid device mode failed to set valid channel", __func__);
3346 return -EINVAL;
3347 }
3348 EXIT();
3349 return 0;
3350}
3351
3352
3353
3354/*
3355 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3356 * This function is used to inform the BSS details to nl80211 interface.
3357 */
3358static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3359 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3360{
3361 struct net_device *dev = pAdapter->dev;
3362 struct wireless_dev *wdev = dev->ieee80211_ptr;
3363 struct wiphy *wiphy = wdev->wiphy;
3364 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3365 int chan_no;
3366 int ie_length;
3367 const char *ie;
3368 unsigned int freq;
3369 struct ieee80211_channel *chan;
3370 int rssi = 0;
3371 struct cfg80211_bss *bss = NULL;
3372
3373 ENTER();
3374
3375 if( NULL == pBssDesc )
3376 {
3377 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3378 return bss;
3379 }
3380
3381 chan_no = pBssDesc->channelId;
3382 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3383 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3384
3385 if( NULL == ie )
3386 {
3387 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3388 return bss;
3389 }
3390
3391#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3392 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3393 {
3394 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3395 }
3396 else
3397 {
3398 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3399 }
3400#else
3401 freq = ieee80211_channel_to_frequency(chan_no);
3402#endif
3403
3404 chan = __ieee80211_get_channel(wiphy, freq);
3405
3406 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3407 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3408 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3409 if (bss == NULL)
3410 {
3411 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3412
3413 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3414 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3415 pBssDesc->capabilityInfo,
3416 pBssDesc->beaconInterval, ie, ie_length,
3417 rssi, GFP_KERNEL ));
3418}
3419 else
3420 {
3421 return bss;
3422 }
3423}
3424
3425
3426
3427/*
3428 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3429 * This function is used to inform the BSS details to nl80211 interface.
3430 */
3431struct cfg80211_bss*
3432wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3433 tSirBssDescription *bss_desc
3434 )
3435{
3436 /*
3437 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3438 already exists in bss data base of cfg80211 for that particular BSS ID.
3439 Using cfg80211_inform_bss_frame to update the bss entry instead of
3440 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3441 now there is no possibility to get the mgmt(probe response) frame from PE,
3442 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3443 cfg80211_inform_bss_frame.
3444 */
3445 struct net_device *dev = pAdapter->dev;
3446 struct wireless_dev *wdev = dev->ieee80211_ptr;
3447 struct wiphy *wiphy = wdev->wiphy;
3448 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003449#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3450 qcom_ie_age *qie_age = NULL;
3451 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3452#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003453 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003454#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003455 const char *ie =
3456 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3457 unsigned int freq;
3458 struct ieee80211_channel *chan;
3459 struct ieee80211_mgmt *mgmt =
3460 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3461 struct cfg80211_bss *bss_status = NULL;
3462 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3463 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003464#ifdef WLAN_OPEN_SOURCE
3465 struct timespec ts;
3466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003467
3468 ENTER();
3469
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003470 if (!mgmt)
3471 return NULL;
3472
Jeff Johnson295189b2012-06-20 16:38:30 -07003473 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003474
3475#ifdef WLAN_OPEN_SOURCE
3476 /* Android does not want the timestamp from the frame.
3477 Instead it wants a monotonic increasing value */
3478 get_monotonic_boottime(&ts);
3479 mgmt->u.probe_resp.timestamp =
3480 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3481#else
3482 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003483 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3484 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003485
3486#endif
3487
Jeff Johnson295189b2012-06-20 16:38:30 -07003488 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3489 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003490
3491#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3492 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3493 /* Assuming this is the last IE, copy at the end */
3494 ie_length -=sizeof(qcom_ie_age);
3495 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3496 qie_age->element_id = QCOM_VENDOR_IE_ID;
3497 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3498 qie_age->oui_1 = QCOM_OUI1;
3499 qie_age->oui_2 = QCOM_OUI2;
3500 qie_age->oui_3 = QCOM_OUI3;
3501 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3502 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3503#endif
3504
Jeff Johnson295189b2012-06-20 16:38:30 -07003505 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3506
3507 mgmt->frame_control |=
3508 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3509
3510#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3511 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3512 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3513 {
3514 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3515 }
3516 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3517 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3518
3519 {
3520 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3521 }
3522 else
3523 {
3524 kfree(mgmt);
3525 return NULL;
3526 }
3527#else
3528 freq = ieee80211_channel_to_frequency(chan_no);
3529#endif
3530 chan = __ieee80211_get_channel(wiphy, freq);
3531
3532 /*To keep the rssi icon of the connected AP in the scan window
3533 *and the rssi icon of the wireless networks in sync
3534 * */
3535 if (( eConnectionState_Associated ==
3536 pAdapter->sessionCtx.station.conn_info.connState ) &&
3537 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3538 pAdapter->sessionCtx.station.conn_info.bssId,
3539 WNI_CFG_BSSID_LEN)))
3540 {
3541 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3542 rssi = (pAdapter->rssi * 100);
3543 }
3544 else
3545 {
3546 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3547 }
3548
3549 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3550 frame_len, rssi, GFP_KERNEL);
3551 kfree(mgmt);
3552 return bss_status;
3553}
3554
3555/*
3556 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3557 * This function is used to update the BSS data base of CFG8011
3558 */
3559struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3560 tCsrRoamInfo *pRoamInfo
3561 )
3562{
3563 tCsrRoamConnectedProfile roamProfile;
3564 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3565 struct cfg80211_bss *bss = NULL;
3566
3567 ENTER();
3568
3569 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3570 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3571
3572 if (NULL != roamProfile.pBssDesc)
3573 {
3574 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3575 &roamProfile);
3576
3577 if (NULL == bss)
3578 {
3579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3580 __func__);
3581 }
3582
3583 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3584 }
3585 else
3586 {
3587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3588 __func__);
3589 }
3590 return bss;
3591}
3592
3593/*
3594 * FUNCTION: wlan_hdd_cfg80211_update_bss
3595 */
3596static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3597 hdd_adapter_t *pAdapter
3598 )
3599{
3600 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3601 tCsrScanResultInfo *pScanResult;
3602 eHalStatus status = 0;
3603 tScanResultHandle pResult;
3604 struct cfg80211_bss *bss_status = NULL;
3605
3606 ENTER();
3607
3608 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3609 {
3610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3611 return -EAGAIN;
3612 }
3613
3614 /*
3615 * start getting scan results and populate cgf80211 BSS database
3616 */
3617 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3618
3619 /* no scan results */
3620 if (NULL == pResult)
3621 {
3622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3623 return status;
3624 }
3625
3626 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3627
3628 while (pScanResult)
3629 {
3630 /*
3631 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3632 * entry already exists in bss data base of cfg80211 for that
3633 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3634 * bss entry instead of cfg80211_inform_bss, But this call expects
3635 * mgmt packet as input. As of now there is no possibility to get
3636 * the mgmt(probe response) frame from PE, converting bss_desc to
3637 * ieee80211_mgmt(probe response) and passing to c
3638 * fg80211_inform_bss_frame.
3639 * */
3640
3641 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3642 &pScanResult->BssDescriptor);
3643
3644
3645 if (NULL == bss_status)
3646 {
3647 hddLog(VOS_TRACE_LEVEL_INFO,
3648 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3649 }
3650 else
3651 {
3652 cfg80211_put_bss(bss_status);
3653 }
3654
3655 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3656 }
3657
3658 sme_ScanResultPurge(hHal, pResult);
3659
3660 return 0;
3661}
3662
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003663void
3664hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3665{
3666 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003667 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3668 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3669 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003670} /****** end hddPrintMacAddr() ******/
3671
3672void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003673hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003674{
3675 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003676 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3677 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3678 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3679 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003680} /****** end hddPrintPmkId() ******/
3681
3682//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3683//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3684
3685//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3686//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3687
3688#define dump_bssid(bssid) \
3689 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003690 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3691 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3692 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003693 }
3694
3695#define dump_pmkid(pMac, pmkid) \
3696 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003697 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3698 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3699 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003700 }
3701
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003702#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003703/*
3704 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3705 * This function is used to notify the supplicant of a new PMKSA candidate.
3706 */
3707int wlan_hdd_cfg80211_pmksa_candidate_notify(
3708 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3709 int index, bool preauth )
3710{
Jeff Johnsone7245742012-09-05 17:12:55 -07003711#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003712 struct net_device *dev = pAdapter->dev;
3713
3714 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003715 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003716
3717 if( NULL == pRoamInfo )
3718 {
3719 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3720 return -EINVAL;
3721 }
3722
3723 dump_bssid(pRoamInfo->bssid);
3724 cfg80211_pmksa_candidate_notify(dev, index,
3725 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003726#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003727 return 0;
3728}
3729#endif //FEATURE_WLAN_LFR
3730
Jeff Johnson295189b2012-06-20 16:38:30 -07003731/*
3732 * FUNCTION: hdd_cfg80211_scan_done_callback
3733 * scanning callback function, called after finishing scan
3734 *
3735 */
3736static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3737 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3738{
3739 struct net_device *dev = (struct net_device *) pContext;
3740 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3741 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003742 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3743 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003744 struct cfg80211_scan_request *req = NULL;
3745 int ret = 0;
3746
3747 ENTER();
3748
3749 hddLog(VOS_TRACE_LEVEL_INFO,
3750 "%s called with halHandle = %p, pContext = %p,"
3751 "scanID = %d, returned status = %d\n",
3752 __func__, halHandle, pContext, (int) scanId, (int) status);
3753
3754 //Block on scan req completion variable. Can't wait forever though.
3755 ret = wait_for_completion_interruptible_timeout(
3756 &pScanInfo->scan_req_completion_event,
3757 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3758 if (!ret)
3759 {
3760 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003761 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003762 }
3763
3764 if(pScanInfo->mScanPending != VOS_TRUE)
3765 {
3766 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003767 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003768 }
3769
3770 /* Check the scanId */
3771 if (pScanInfo->scanId != scanId)
3772 {
3773 hddLog(VOS_TRACE_LEVEL_INFO,
3774 "%s called with mismatched scanId pScanInfo->scanId = %d "
3775 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3776 (int) scanId);
3777 }
3778
Jeff Johnson295189b2012-06-20 16:38:30 -07003779 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3780 pAdapter);
3781
3782 if (0 > ret)
3783 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3784
3785
3786 /* If any client wait scan result through WEXT
3787 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003788 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003789 {
3790 /* The other scan request waiting for current scan finish
3791 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003792 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003793 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003794 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003795 }
3796 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003797 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003798 {
3799 struct net_device *dev = pAdapter->dev;
3800 union iwreq_data wrqu;
3801 int we_event;
3802 char *msg;
3803
3804 memset(&wrqu, '\0', sizeof(wrqu));
3805 we_event = SIOCGIWSCAN;
3806 msg = NULL;
3807 wireless_send_event(dev, we_event, &wrqu, msg);
3808 }
3809 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003810 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003811
3812 /* Get the Scan Req */
3813 req = pAdapter->request;
3814
3815 if (!req)
3816 {
3817 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003818 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003819 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003820 }
3821
3822 /*
3823 * setting up 0, just in case.
3824 */
3825 req->n_ssids = 0;
3826 req->n_channels = 0;
3827 req->ie = 0;
3828
Jeff Johnson295189b2012-06-20 16:38:30 -07003829 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07003830 /* Scan is no longer pending */
3831 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003832
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07003833 /*
3834 * cfg80211_scan_done informing NL80211 about completion
3835 * of scanning
3836 */
3837 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08003838 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07003839
Jeff Johnsone7245742012-09-05 17:12:55 -07003840allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003841 /* release the wake lock at the end of the scan*/
3842 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003843
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07003844 /* Acquire wakelock to handle the case where APP's tries to suspend
3845 * immediatly after the driver gets connect request(i.e after scan)
3846 * from supplicant, this result in app's is suspending and not able
3847 * to process the connect request to AP */
3848 hdd_allow_suspend_timeout(100);
3849
Jeff Johnson295189b2012-06-20 16:38:30 -07003850 EXIT();
3851 return 0;
3852}
3853
3854/*
3855 * FUNCTION: wlan_hdd_cfg80211_scan
3856 * this scan respond to scan trigger and update cfg80211 scan database
3857 * later, scan dump command can be used to recieve scan results
3858 */
3859int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, struct net_device *dev,
3860 struct cfg80211_scan_request *request)
3861{
3862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
3863 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3864 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3865 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3866 tCsrScanRequest scanRequest;
3867 tANI_U8 *channelList = NULL, i;
3868 v_U32_t scanId = 0;
3869 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003870 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003871#ifdef WLAN_FEATURE_P2P
3872 v_U8_t* pP2pIe = NULL;
3873#endif
3874
3875 ENTER();
3876
3877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3878 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003879
3880 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
3881 (eConnectionState_Connecting ==
3882 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
3883 {
3884 hddLog(VOS_TRACE_LEVEL_ERROR,
3885 "%s: Connection in progress: Scan request denied (EBUSY)", __func__);
3886 return -EBUSY;
3887 }
3888
Jeff Johnson295189b2012-06-20 16:38:30 -07003889#ifdef WLAN_BTAMP_FEATURE
3890 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003891 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07003892 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08003893 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003894 "%s: No scanning when AMP is on", __func__);
3895 return -EOPNOTSUPP;
3896 }
3897#endif
3898 //Scan on any other interface is not supported.
3899 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
3900 {
3901 hddLog(VOS_TRACE_LEVEL_ERROR,
3902 "%s: Not scanning on device_mode = %d",
3903 __func__, pAdapter->device_mode);
3904 return -EOPNOTSUPP;
3905 }
3906
3907 if (TRUE == pScanInfo->mScanPending)
3908 {
3909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
3910 return -EBUSY;
3911 }
3912
3913 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3914 {
3915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3916 "%s:LOGP in Progress. Ignore!!!", __func__);
3917 return -EAGAIN;
3918 }
3919
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07003920 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
3921 {
3922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3923 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
3924 return -EAGAIN;
3925 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07003926 //Don't Allow Scan and return busy if Remain On
3927 //Channel and action frame is pending
3928 //Otherwise Cancel Remain On Channel and allow Scan
3929 //If no action frame pending
3930 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
3931 {
3932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
3933 return -EBUSY;
3934 }
3935
Jeff Johnson295189b2012-06-20 16:38:30 -07003936 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
3937 {
3938 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
3939 "%s: Aquire lock fail", __func__);
3940 return -EAGAIN;
3941 }
3942 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
3943 {
3944 hddLog(VOS_TRACE_LEVEL_WARN,
3945 "%s: MAX TM Level Scan not allowed", __func__);
3946 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3947 return -EBUSY;
3948 }
3949 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
3950
3951 vos_mem_zero( &scanRequest, sizeof(scanRequest));
3952
3953 if (NULL != request)
3954 {
3955 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
3956 (int)request->n_ssids);
3957
3958 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
3959 * Becasue of this, driver is assuming that this is not wildcard scan and so
3960 * is not aging out the scan results.
3961 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07003962 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 {
3964 request->n_ssids = 0;
3965 }
3966
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003967 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 {
3969 tCsrSSIDInfo *SsidInfo;
3970 int j;
3971 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
3972 /* Allocate num_ssid tCsrSSIDInfo structure */
3973 SsidInfo = scanRequest.SSIDs.SSIDList =
3974 ( tCsrSSIDInfo *)vos_mem_malloc(
3975 request->n_ssids*sizeof(tCsrSSIDInfo));
3976
3977 if(NULL == scanRequest.SSIDs.SSIDList)
3978 {
3979 hddLog(VOS_TRACE_LEVEL_ERROR,
3980 "memory alloc failed SSIDInfo buffer");
3981 return -ENOMEM;
3982 }
3983
3984 /* copy all the ssid's and their length */
3985 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
3986 {
3987 /* get the ssid length */
3988 SsidInfo->SSID.length = request->ssids[j].ssid_len;
3989 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
3990 SsidInfo->SSID.length);
3991 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
3992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
3993 j, SsidInfo->SSID.ssId);
3994 }
3995 /* set the scan type to active */
3996 scanRequest.scanType = eSIR_ACTIVE_SCAN;
3997 }
3998 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
3999 {
4000 /* set the scan type to active */
4001 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4002 }
4003 else
4004 {
4005 /*Set the scan type to default type, in this case it is ACTIVE*/
4006 scanRequest.scanType = pScanInfo->scan_mode;
4007 }
4008 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4009 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4010 }
4011 else
4012 {
4013 /* set the scan type to active */
4014 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4015 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4016
4017 /* set min and max channel time to zero */
4018 scanRequest.minChnTime = 0;
4019 scanRequest.maxChnTime = 0;
4020 }
4021
4022 /* set BSSType to default type */
4023 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4024
4025 /*TODO: scan the requested channels only*/
4026
4027 /*Right now scanning all the channels */
4028 if( request )
4029 {
4030 if( request->n_channels )
4031 {
4032 channelList = vos_mem_malloc( request->n_channels );
4033 if( NULL == channelList )
4034 {
4035 status = -ENOMEM;
4036 goto free_mem;
4037 }
4038
4039 for( i = 0 ; i < request->n_channels ; i++ )
4040 channelList[i] = request->channels[i]->hw_value;
4041 }
4042
4043 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4044 scanRequest.ChannelInfo.ChannelList = channelList;
4045
4046 /* set requestType to full scan */
4047 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004048
4049 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4050 * search (Flush on both full scan and social scan but not on single
4051 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4052 */
4053
4054 /* Supplicant does single channel scan after 8-way handshake
4055 * and in that case driver shoudnt flush scan results. If
4056 * driver flushes the scan results here and unfortunately if
4057 * the AP doesnt respond to our probe req then association
4058 * fails which is not desired
4059 */
4060
4061 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4062 {
4063 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4064 pAdapter->sessionId );
4065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004066
4067 if( request->ie_len )
4068 {
4069 /* save this for future association (join requires this) */
4070 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4071 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4072 pScanInfo->scanAddIE.length = request->ie_len;
4073
4074 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004075 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4076 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004077 )
4078 {
4079 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4080 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4081 }
4082
4083 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4084 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4085
4086#ifdef WLAN_FEATURE_P2P
4087 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4088 request->ie_len);
4089 if (pP2pIe != NULL)
4090 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004091#ifdef WLAN_FEATURE_P2P_DEBUG
4092 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4093 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4094 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4095 {
4096 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4097 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4098 "Go nego completed to Connection is started");
4099 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4100 "for 8way Handshake");
4101 }
4102 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4103 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4104 {
4105 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4106 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4107 "Disconnected state to Connection is started");
4108 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4109 "for 4way Handshake");
4110 }
4111#endif
4112
Jeff Johnsone7245742012-09-05 17:12:55 -07004113 /* no_cck will be set during p2p find to disable 11b rates */
4114 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004115 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004116 hddLog(VOS_TRACE_LEVEL_INFO,
4117 "%s: This is a P2P Search", __func__);
4118 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004119
Jeff Johnsone7245742012-09-05 17:12:55 -07004120 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4121 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004122 /* set requestType to P2P Discovery */
4123 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004124 }
4125
4126 /*
4127 Skip Dfs Channel in case of P2P Search
4128 if it is set in ini file
4129 */
4130 if(cfg_param->skipDfsChnlInP2pSearch)
4131 {
4132 scanRequest.skipDfsChnlInP2pSearch = 1;
4133 }
4134 else
4135 {
4136 scanRequest.skipDfsChnlInP2pSearch = 0;
4137 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004138
Jeff Johnson295189b2012-06-20 16:38:30 -07004139 }
4140 }
4141#endif
4142 }
4143 }
4144
4145 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4146
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004147 /* acquire the wakelock to avoid the apps suspend during the scan. To
4148 * address the following issues.
4149 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4150 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4151 * for long time, this result in apps running at full power for long time.
4152 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4153 * be stuck in full power because of resume BMPS
4154 */
4155 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004156
4157 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 pAdapter->sessionId, &scanRequest, &scanId,
4159 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 if (eHAL_STATUS_SUCCESS != status)
4162 {
4163 hddLog(VOS_TRACE_LEVEL_ERROR,
4164 "%s: sme_ScanRequest returned error %d", __func__, status);
4165 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004166 if(eHAL_STATUS_RESOURCES == status)
4167 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004168 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 -07004169 status = -EBUSY;
4170 } else {
4171 status = -EIO;
4172 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004173 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 goto free_mem;
4175 }
4176
4177 pScanInfo->mScanPending = TRUE;
4178 pAdapter->request = request;
4179 pScanInfo->scanId = scanId;
4180
4181 complete(&pScanInfo->scan_req_completion_event);
4182
4183free_mem:
4184 if( scanRequest.SSIDs.SSIDList )
4185 {
4186 vos_mem_free(scanRequest.SSIDs.SSIDList);
4187 }
4188
4189 if( channelList )
4190 vos_mem_free( channelList );
4191
4192 EXIT();
4193
4194 return status;
4195}
4196
4197/*
4198 * FUNCTION: wlan_hdd_cfg80211_connect_start
4199 * This function is used to start the association process
4200 */
4201int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004202 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004203{
4204 int status = 0;
4205 hdd_wext_state_t *pWextState;
4206 v_U32_t roamId;
4207 tCsrRoamProfile *pRoamProfile;
4208 eMib_dot11DesiredBssType connectedBssType;
4209 eCsrAuthType RSNAuthType;
4210
4211 ENTER();
4212
4213 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4214
4215 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4216 {
4217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4218 return -EINVAL;
4219 }
4220
4221 pRoamProfile = &pWextState->roamProfile;
4222
4223 if (pRoamProfile)
4224 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004225 int ret = 0;
4226 hdd_station_ctx_t *pHddStaCtx;
4227 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4228 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4229
4230 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4231 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4232 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 {
4234 /* Issue disconnect to CSR */
4235 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4236 if( eHAL_STATUS_SUCCESS ==
4237 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4238 pAdapter->sessionId,
4239 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4240 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004241 ret = wait_for_completion_interruptible_timeout(
4242 &pAdapter->disconnect_comp_var,
4243 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4244 if (0 == ret)
4245 {
4246 VOS_ASSERT(0);
4247 }
4248 }
4249 }
4250 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4251 {
4252 ret = wait_for_completion_interruptible_timeout(
4253 &pAdapter->disconnect_comp_var,
4254 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4255 if (0 == ret)
4256 {
4257 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 }
4259 }
4260
4261 if (HDD_WMM_USER_MODE_NO_QOS ==
4262 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4263 {
4264 /*QoS not enabled in cfg file*/
4265 pRoamProfile->uapsd_mask = 0;
4266 }
4267 else
4268 {
4269 /*QoS enabled, update uapsd mask from cfg file*/
4270 pRoamProfile->uapsd_mask =
4271 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4272 }
4273
4274 pRoamProfile->SSIDs.numOfSSIDs = 1;
4275 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4276 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4277 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4278 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4279 ssid, ssid_len);
4280
4281 if (bssid)
4282 {
4283 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4284 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4285 WNI_CFG_BSSID_LEN);
4286 /* Save BSSID in seperate variable as well, as RoamProfile
4287 BSSID is getting zeroed out in the association process. And in
4288 case of join failure we should send valid BSSID to supplicant
4289 */
4290 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4291 WNI_CFG_BSSID_LEN);
4292 }
4293
4294 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4295 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4296 {
4297 /*set gen ie*/
4298 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4299 /*set auth*/
4300 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4301 }
4302 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4303 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4304 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4305 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4306 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4307 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4308 )
4309 {
4310 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4311 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4312 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4313 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4314 eCSR_AUTH_TYPE_AUTOSWITCH;
4315 pWextState->roamProfile.AuthType.authType[0] =
4316 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4317 }
4318#ifdef FEATURE_WLAN_WAPI
4319 if (pAdapter->wapi_info.nWapiMode)
4320 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004321 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004322 switch (pAdapter->wapi_info.wapiAuthMode)
4323 {
4324 case WAPI_AUTH_MODE_PSK:
4325 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004326 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004327 pAdapter->wapi_info.wapiAuthMode);
4328 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4329 break;
4330 }
4331 case WAPI_AUTH_MODE_CERT:
4332 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004333 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004334 pAdapter->wapi_info.wapiAuthMode);
4335 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4336 break;
4337 }
4338 } // End of switch
4339 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4340 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4341 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004342 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004343 pRoamProfile->AuthType.numEntries = 1;
4344 pRoamProfile->EncryptionType.numEntries = 1;
4345 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4346 pRoamProfile->mcEncryptionType.numEntries = 1;
4347 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4348 }
4349 }
4350#endif /* FEATURE_WLAN_WAPI */
4351 pRoamProfile->csrPersona = pAdapter->device_mode;
4352
Jeff Johnson32d95a32012-09-10 13:15:23 -07004353 if( operatingChannel )
4354 {
4355 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4356 pRoamProfile->ChannelInfo.numOfChannels = 1;
4357 }
4358
Jeff Johnson295189b2012-06-20 16:38:30 -07004359 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4360 pAdapter->sessionId, pRoamProfile, &roamId);
4361
Jeff Johnson32d95a32012-09-10 13:15:23 -07004362 pRoamProfile->ChannelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 pRoamProfile->ChannelInfo.numOfChannels = 0;
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304364
4365 if( (eHAL_STATUS_SUCCESS == status) &&
4366 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4367
4368 {
4369 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4370 eConnectionState_Connecting);
4371 }
4372
4373 if( status != eHAL_STATUS_SUCCESS )
4374 {
4375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect failed with "
4376 "status %d", __func__, status);
4377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004378 }
4379 else
4380 {
4381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4382 return -EINVAL;
4383 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004384 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004385 return status;
4386}
4387
4388/*
4389 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4390 * This function is used to set the authentication type (OPEN/SHARED).
4391 *
4392 */
4393static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4394 enum nl80211_auth_type auth_type)
4395{
4396 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4397 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4398
4399 ENTER();
4400
4401 /*set authentication type*/
4402 switch (auth_type)
4403 {
4404 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4405 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004406#ifdef WLAN_FEATURE_VOWIFI_11R
4407 case NL80211_AUTHTYPE_FT:
4408#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004409 hddLog(VOS_TRACE_LEVEL_INFO,
4410 "%s: set authentication type to OPEN", __func__);
4411 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4412 break;
4413
4414 case NL80211_AUTHTYPE_SHARED_KEY:
4415 hddLog(VOS_TRACE_LEVEL_INFO,
4416 "%s: set authentication type to SHARED", __func__);
4417 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4418 break;
4419#ifdef FEATURE_WLAN_CCX
4420 case NL80211_AUTHTYPE_NETWORK_EAP:
4421 hddLog(VOS_TRACE_LEVEL_INFO,
4422 "%s: set authentication type to CCKM WPA", __func__);
4423 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4424 break;
4425#endif
4426
4427
4428 default:
4429 hddLog(VOS_TRACE_LEVEL_ERROR,
4430 "%s: Unsupported authentication type %d", __func__,
4431 auth_type);
4432 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4433 return -EINVAL;
4434 }
4435
4436 pWextState->roamProfile.AuthType.authType[0] =
4437 pHddStaCtx->conn_info.authType;
4438 return 0;
4439}
4440
4441/*
4442 * FUNCTION: wlan_hdd_set_akm_suite
4443 * This function is used to set the key mgmt type(PSK/8021x).
4444 *
4445 */
4446static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4447 u32 key_mgmt
4448 )
4449{
4450 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4451 ENTER();
4452
4453 /*set key mgmt type*/
4454 switch(key_mgmt)
4455 {
4456 case WLAN_AKM_SUITE_PSK:
4457 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4458 __func__);
4459 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4460 break;
4461
4462 case WLAN_AKM_SUITE_8021X:
4463 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4464 __func__);
4465 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4466 break;
4467#ifdef FEATURE_WLAN_CCX
4468#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4469#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4470 case WLAN_AKM_SUITE_CCKM:
4471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4472 __func__);
4473 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4474 break;
4475#endif
4476
4477 default:
4478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4479 __func__, key_mgmt);
4480 return -EINVAL;
4481
4482 }
4483 return 0;
4484}
4485
4486/*
4487 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4488 * This function is used to set the encryption type
4489 * (NONE/WEP40/WEP104/TKIP/CCMP).
4490 */
4491static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4492 u32 cipher,
4493 bool ucast
4494 )
4495{
4496 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4497 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4498 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4499
4500 ENTER();
4501
4502 if (!cipher)
4503 {
4504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4505 __func__, cipher);
4506 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4507 }
4508 else
4509 {
4510
4511 /*set encryption method*/
4512 switch (cipher)
4513 {
4514 case IW_AUTH_CIPHER_NONE:
4515 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4516 break;
4517
4518 case WLAN_CIPHER_SUITE_WEP40:
4519 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4520 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4521 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4522 else
4523 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4524 break;
4525
4526 case WLAN_CIPHER_SUITE_WEP104:
4527 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4528 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4529 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4530 else
4531 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4532 break;
4533
4534 case WLAN_CIPHER_SUITE_TKIP:
4535 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4536 break;
4537
4538 case WLAN_CIPHER_SUITE_CCMP:
4539 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4540 break;
4541#ifdef FEATURE_WLAN_WAPI
4542 case WLAN_CIPHER_SUITE_SMS4:
4543 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4544 break;
4545#endif
4546
4547#ifdef FEATURE_WLAN_CCX
4548 case WLAN_CIPHER_SUITE_KRK:
4549 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4550 break;
4551#endif
4552 default:
4553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4554 __func__, cipher);
4555 return -EOPNOTSUPP;
4556 }
4557 }
4558
4559 if (ucast)
4560 {
4561 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4562 __func__, encryptionType);
4563 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4564 pWextState->roamProfile.EncryptionType.numEntries = 1;
4565 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4566 encryptionType;
4567 }
4568 else
4569 {
4570 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4571 __func__, encryptionType);
4572 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4573 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4574 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4575 }
4576
4577 return 0;
4578}
4579
4580
4581/*
4582 * FUNCTION: wlan_hdd_cfg80211_set_ie
4583 * This function is used to parse WPA/RSN IE's.
4584 */
4585int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4586 u8 *ie,
4587 size_t ie_len
4588 )
4589{
4590 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4591 u8 *genie = ie;
4592 v_U16_t remLen = ie_len;
4593#ifdef FEATURE_WLAN_WAPI
4594 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4595 u16 *tmp;
4596 v_U16_t akmsuiteCount;
4597 int *akmlist;
4598#endif
4599 ENTER();
4600
4601 /* clear previous assocAddIE */
4602 pWextState->assocAddIE.length = 0;
4603 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4604
4605 while (remLen >= 2)
4606 {
4607 v_U16_t eLen = 0;
4608 v_U8_t elementId;
4609 elementId = *genie++;
4610 eLen = *genie++;
4611 remLen -= 2;
4612
4613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4614 __func__, elementId, eLen);
4615
4616 switch ( elementId )
4617 {
4618 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004619 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 -07004620 {
4621 hddLog(VOS_TRACE_LEVEL_ERROR,
4622 "%s: Invalid WPA IE", __func__);
4623 return -EINVAL;
4624 }
4625 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4626 {
4627 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4628 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4629 __func__, eLen + 2);
4630
4631 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4632 {
4633 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE. "
4634 "Need bigger buffer space\n");
4635 VOS_ASSERT(0);
4636 return -ENOMEM;
4637 }
4638 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4639 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4640 pWextState->assocAddIE.length += eLen + 2;
4641
4642 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4643 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4644 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4645 }
4646 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4647 {
4648 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4649 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4650 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4651 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4652 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4653 }
4654#ifdef WLAN_FEATURE_P2P
4655 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4656 P2P_OUI_TYPE_SIZE))
4657 /*Consider P2P IE, only for P2P Client */
4658 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4659 {
4660 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4661 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4662 __func__, eLen + 2);
4663
4664 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4665 {
4666 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4667 "Need bigger buffer space\n");
4668 VOS_ASSERT(0);
4669 return -ENOMEM;
4670 }
4671 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4672 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4673 pWextState->assocAddIE.length += eLen + 2;
4674
4675 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4676 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4677 }
4678#endif
4679#ifdef WLAN_FEATURE_WFD
4680 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4681 WFD_OUI_TYPE_SIZE))
4682 /*Consider WFD IE, only for P2P Client */
4683 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4684 {
4685 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4686 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4687 __func__, eLen + 2);
4688
4689 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4690 {
4691 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4692 "Need bigger buffer space\n");
4693 VOS_ASSERT(0);
4694 return -ENOMEM;
4695 }
4696 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4697 // WPS IE + P2P IE + WFD IE
4698 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4699 pWextState->assocAddIE.length += eLen + 2;
4700
4701 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4702 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4703 }
4704#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004705 /* Appending HS 2.0 Indication Element in Assiciation Request */
4706 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004707 HS20_OUI_TYPE_SIZE)) )
4708 {
4709 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4710 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4711 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004712
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004713 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4714 {
4715 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4716 "Need bigger buffer space\n");
4717 VOS_ASSERT(0);
4718 return -ENOMEM;
4719 }
4720 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4721 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004722
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004723 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4724 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4725 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004726
Jeff Johnson295189b2012-06-20 16:38:30 -07004727 break;
4728 case DOT11F_EID_RSN:
4729 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4730 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4731 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4732 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4733 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4734 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004735 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4736 case DOT11F_EID_EXTCAP:
4737 {
4738 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4739 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
4740 __func__, eLen + 2);
4741
4742 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4743 {
4744 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accomadate assocAddIE "
4745 "Need bigger buffer space\n");
4746 VOS_ASSERT(0);
4747 return -ENOMEM;
4748 }
4749 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4750 pWextState->assocAddIE.length += eLen + 2;
4751
4752 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4753 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4754 break;
4755 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004756#ifdef FEATURE_WLAN_WAPI
4757 case WLAN_EID_WAPI:
4758 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
4759 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
4760 pAdapter->wapi_info.nWapiMode);
4761 tmp = (u16 *)ie;
4762 tmp = tmp + 2; // Skip element Id and Len, Version
4763 akmsuiteCount = WPA_GET_LE16(tmp);
4764 tmp = tmp + 1;
4765 akmlist = (int *)(tmp);
4766 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
4767 {
4768 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
4769 }
4770 else
4771 {
4772 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
4773 VOS_ASSERT(0);
4774 return -EINVAL;
4775 }
4776
4777 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
4778 {
4779 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004780 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004781 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
4782 }
4783 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
4784 {
4785 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004786 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004787 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
4788 }
4789 break;
4790#endif
4791 default:
4792 hddLog (VOS_TRACE_LEVEL_ERROR,
4793 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004794 /* when Unknown IE is received we should break and continue
4795 * to the next IE in the buffer instead we were returning
4796 * so changing this to break */
4797 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07004798 }
4799 genie += eLen;
4800 remLen -= eLen;
4801 }
4802 EXIT();
4803 return 0;
4804}
4805
4806/*
4807 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4808 * This function is used to initialize the security
4809 * parameters during connect operation.
4810 */
4811int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
4812 struct cfg80211_connect_params *req
4813 )
4814{
4815 int status = 0;
4816 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4817 ENTER();
4818
4819 /*set wpa version*/
4820 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
4821
4822 if (req->crypto.wpa_versions)
4823 {
4824 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
4825 && ( (req->ie_len)
4826 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
4827 // Make sure that it is including a WPA IE.
4828 /* Currently NL is putting WPA version 1 even for open,
4829 * since p2p ie is also put in same buffer.
4830 * */
4831 {
4832 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
4833 }
4834 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
4835 {
4836 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
4837 }
4838 }
4839
4840 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
4841 pWextState->wpaVersion);
4842
4843 /*set authentication type*/
4844 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
4845
4846 if (0 > status)
4847 {
4848 hddLog(VOS_TRACE_LEVEL_ERROR,
4849 "%s: failed to set authentication type ", __func__);
4850 return status;
4851 }
4852
4853 /*set key mgmt type*/
4854 if (req->crypto.n_akm_suites)
4855 {
4856 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
4857 if (0 > status)
4858 {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
4860 __func__);
4861 return status;
4862 }
4863 }
4864
4865 /*set pairwise cipher type*/
4866 if (req->crypto.n_ciphers_pairwise)
4867 {
4868 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
4869 req->crypto.ciphers_pairwise[0], true);
4870 if (0 > status)
4871 {
4872 hddLog(VOS_TRACE_LEVEL_ERROR,
4873 "%s: failed to set unicast cipher type", __func__);
4874 return status;
4875 }
4876 }
4877 else
4878 {
4879 /*Reset previous cipher suite to none*/
4880 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
4881 if (0 > status)
4882 {
4883 hddLog(VOS_TRACE_LEVEL_ERROR,
4884 "%s: failed to set unicast cipher type", __func__);
4885 return status;
4886 }
4887 }
4888
4889 /*set group cipher type*/
4890 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
4891 false);
4892
4893 if (0 > status)
4894 {
4895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
4896 __func__);
4897 return status;
4898 }
4899
4900 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
4901 if (req->ie_len)
4902 {
4903 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
4904 if ( 0 > status)
4905 {
4906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
4907 __func__);
4908 return status;
4909 }
4910 }
4911
4912 /*incase of WEP set default key information*/
4913 if (req->key && req->key_len)
4914 {
4915 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
4916 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
4917 )
4918 {
4919 if ( IW_AUTH_KEY_MGMT_802_1X
4920 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
4921 {
4922 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
4923 __func__);
4924 return -EOPNOTSUPP;
4925 }
4926 else
4927 {
4928 u8 key_len = req->key_len;
4929 u8 key_idx = req->key_idx;
4930
4931 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
4932 && (CSR_MAX_NUM_KEY > key_idx)
4933 )
4934 {
4935 hddLog(VOS_TRACE_LEVEL_INFO,
4936 "%s: setting default wep key, key_idx = %hu key_len %hu",
4937 __func__, key_idx, key_len);
4938 vos_mem_copy(
4939 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
4940 req->key, key_len);
4941 pWextState->roamProfile.Keys.KeyLength[key_idx] =
4942 (u8)key_len;
4943 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
4944 }
4945 }
4946 }
4947 }
4948
4949 return status;
4950}
4951
4952/*
4953 * FUNCTION: wlan_hdd_cfg80211_set_privacy
4954 * This function is used to initialize the security
4955 * parameters during connect operation.
4956 */
4957static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
4958 struct net_device *ndev,
4959 struct cfg80211_connect_params *req
4960 )
4961{
4962 int status = 0;
4963 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4964 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
4965 hdd_context_t *pHddCtx = NULL;
4966
4967 ENTER();
4968
4969 hddLog(VOS_TRACE_LEVEL_INFO,
4970 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
4971
4972 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
4973 {
4974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4975 "%s:LOGP in Progress. Ignore!!!", __func__);
4976 return -EAGAIN;
4977 }
4978
4979#ifdef WLAN_BTAMP_FEATURE
4980 //Infra connect not supported when AMP traffic is on.
4981 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
4982 {
4983 hddLog(VOS_TRACE_LEVEL_ERROR,
4984 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004985 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 }
4987#endif
4988 /*initialise security parameters*/
4989 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
4990
4991 if ( 0 > status)
4992 {
4993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
4994 __func__);
4995 return status;
4996 }
4997
4998 //If Device Mode is Station Concurrent Sessions Exit BMps
4999 //P2P Mode will be taken care in Open/close adaptor
5000 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5001 (vos_concurrent_sessions_running()))
5002 {
5003 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5004
5005 if (NULL != pVosContext)
5006 {
5007 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5008 if(NULL != pHddCtx)
5009 {
5010 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5011 }
5012 }
5013 }
5014
Mohit Khanna765234a2012-09-11 15:08:35 -07005015 if ( req->channel )
5016 {
5017 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5018 req->ssid_len, req->bssid,
5019 req->channel->hw_value);
5020 }
5021 else
5022 {
5023 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5024 req->ssid_len, req->bssid,
5025 0);
5026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005027
5028 if (0 > status)
5029 {
5030 //ReEnable BMPS if disabled
5031 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5032 (NULL != pHddCtx))
5033 {
5034 //ReEnable Bmps and Imps back
5035 hdd_enable_bmps_imps(pHddCtx);
5036 }
5037
5038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5039 return status;
5040 }
5041 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5042 EXIT();
5043 return status;
5044}
5045
5046
5047/*
5048 * FUNCTION: wlan_hdd_cfg80211_disconnect
5049 * This function is used to issue a disconnect request to SME
5050 */
5051static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5052 struct net_device *dev,
5053 u16 reason
5054 )
5055{
5056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5057 tCsrRoamProfile *pRoamProfile =
5058 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5059 int status = 0;
5060 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5061
5062 ENTER();
5063
5064 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5065 __func__,pAdapter->device_mode);
5066
5067 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5068 __func__, reason);
5069
5070 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5071 {
5072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5073 "%s:LOGP in Progress. Ignore!!!",__func__);
5074 return -EAGAIN;
5075 }
5076 if (NULL != pRoamProfile)
5077 {
5078 /*issue disconnect request to SME, if station is in connected state*/
5079 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5080 {
5081 eCsrRoamDisconnectReason reasonCode =
5082 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5083 switch(reason)
5084 {
5085 case WLAN_REASON_MIC_FAILURE:
5086 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5087 break;
5088
5089 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5090 case WLAN_REASON_DISASSOC_AP_BUSY:
5091 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5092 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5093 break;
5094
5095 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5096 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5097 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5098 break;
5099
5100 case WLAN_REASON_DEAUTH_LEAVING:
5101 default:
5102 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5103 break;
5104 }
5105 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5106 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5107 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5108
5109 /*issue disconnect*/
5110 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5111 pAdapter->sessionId, reasonCode);
5112
5113 if ( 0 != status)
5114 {
5115 hddLog(VOS_TRACE_LEVEL_ERROR,
5116 "%s csrRoamDisconnect failure, returned %d \n",
5117 __func__, (int)status );
5118 return -EINVAL;
5119 }
5120
5121 wait_for_completion_interruptible_timeout(
5122 &pAdapter->disconnect_comp_var,
5123 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5124
5125
5126 /*stop tx queues*/
5127 netif_tx_disable(dev);
5128 netif_carrier_off(dev);
5129 }
5130 }
5131 else
5132 {
5133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5134 }
5135
5136 return status;
5137}
5138
5139/*
5140 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5141 * This function is used to initialize the security
5142 * settings in IBSS mode.
5143 */
5144static int wlan_hdd_cfg80211_set_privacy_ibss(
5145 hdd_adapter_t *pAdapter,
5146 struct cfg80211_ibss_params *params
5147 )
5148{
5149 int status = 0;
5150 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5151 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5153
5154 ENTER();
5155
5156 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5157
5158 if (params->ie_len && ( NULL != params->ie) )
5159 {
5160 if (WLAN_EID_RSN == params->ie[0])
5161 {
5162 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5163 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5164 }
5165 else
5166 {
5167 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5168 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5169 }
5170 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5171
5172 if (0 > status)
5173 {
5174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5175 __func__);
5176 return status;
5177 }
5178 }
5179
5180 pWextState->roamProfile.AuthType.authType[0] =
5181 pHddStaCtx->conn_info.authType =
5182 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5183
5184 if (params->privacy)
5185 {
5186 /* Security enabled IBSS, At this time there is no information available
5187 * about the security paramters, so initialise the encryption type to
5188 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5189 * The correct security parameters will be updated later in
5190 * wlan_hdd_cfg80211_add_key */
5191 /* Hal expects encryption type to be set inorder
5192 *enable privacy bit in beacons */
5193
5194 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5195 }
5196
5197 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5198 pWextState->roamProfile.EncryptionType.numEntries = 1;
5199 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5200
5201 return status;
5202}
5203
5204/*
5205 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5206 * This function is used to create/join an IBSS
5207 */
5208static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5209 struct net_device *dev,
5210 struct cfg80211_ibss_params *params
5211 )
5212{
5213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5214 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5215 tCsrRoamProfile *pRoamProfile;
5216 int status;
5217 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5218
5219 ENTER();
5220
5221 hddLog(VOS_TRACE_LEVEL_INFO,
5222 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5223
5224 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5225 {
5226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5227 "%s:LOGP in Progress. Ignore!!!", __func__);
5228 return -EAGAIN;
5229 }
5230
5231 if (NULL == pWextState)
5232 {
5233 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5234 __func__);
5235 return -EIO;
5236 }
5237
5238 pRoamProfile = &pWextState->roamProfile;
5239
5240 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5241 {
5242 hddLog (VOS_TRACE_LEVEL_ERROR,
5243 "%s Interface type is not set to IBSS \n", __func__);
5244 return -EINVAL;
5245 }
5246
5247 /* Set Channel */
5248 if (NULL != params->channel)
5249 {
5250 u8 channelNum;
5251 if (IEEE80211_BAND_5GHZ == params->channel->band)
5252 {
5253 hddLog(VOS_TRACE_LEVEL_ERROR,
5254 "%s: IBSS join is called with unsupported band %d",
5255 __func__, params->channel->band);
5256 return -EOPNOTSUPP;
5257 }
5258
5259 /* Get channel number */
5260 channelNum =
5261 ieee80211_frequency_to_channel(params->channel->center_freq);
5262
5263 /*TODO: use macro*/
5264 if (14 >= channelNum)
5265 {
5266 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5267 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5268 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5269 int indx;
5270
5271 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5272 validChan, &numChans))
5273 {
5274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5275 __func__);
5276 return -EOPNOTSUPP;
5277 }
5278
5279 for (indx = 0; indx < numChans; indx++)
5280 {
5281 if (channelNum == validChan[indx])
5282 {
5283 break;
5284 }
5285 }
5286 if (indx >= numChans)
5287 {
5288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5289 __func__, channelNum);
5290 return -EINVAL;
5291 }
5292 /* Set the Operational Channel */
5293 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5294 channelNum);
5295 pRoamProfile->ChannelInfo.numOfChannels = 1;
5296 pHddStaCtx->conn_info.operationChannel = channelNum;
5297 pRoamProfile->ChannelInfo.ChannelList =
5298 &pHddStaCtx->conn_info.operationChannel;
5299 }
5300 else
5301 {
5302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5303 __func__, channelNum);
5304 return -EINVAL;
5305 }
5306 }
5307
5308 /* Initialize security parameters */
5309 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5310 if (status < 0)
5311 {
5312 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5313 __func__);
5314 return status;
5315 }
5316
5317 /* Issue connect start */
5318 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005319 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005320
5321 if (0 > status)
5322 {
5323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5324 return status;
5325 }
5326
5327 return 0;
5328}
5329
5330/*
5331 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5332 * This function is used to leave an IBSS
5333 */
5334static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5335 struct net_device *dev
5336 )
5337{
5338 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5339 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5340 tCsrRoamProfile *pRoamProfile;
5341
5342 ENTER();
5343
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005344 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5345 {
5346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5347 "%s:LOGP in Progress. Ignore!!!", __func__);
5348 return -EAGAIN;
5349 }
5350
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5352 if (NULL == pWextState)
5353 {
5354 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5355 __func__);
5356 return -EIO;
5357 }
5358
5359 pRoamProfile = &pWextState->roamProfile;
5360
5361 /* Issue disconnect only if interface type is set to IBSS */
5362 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5363 {
5364 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5365 __func__);
5366 return -EINVAL;
5367 }
5368
5369 /* Issue Disconnect request */
5370 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5371 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5372 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5373
5374 return 0;
5375}
5376
5377/*
5378 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5379 * This function is used to set the phy parameters
5380 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5381 */
5382static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5383 u32 changed)
5384{
5385 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5386 tHalHandle hHal = pHddCtx->hHal;
5387
5388 ENTER();
5389
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005390 if ( pHddCtx->isLogpInProgress )
5391 {
5392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5393 "%s:LOGP in Progress. Ignore!!!", __func__);
5394 return -EAGAIN;
5395 }
5396
Jeff Johnson295189b2012-06-20 16:38:30 -07005397 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5398 {
5399 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5400 WNI_CFG_RTS_THRESHOLD_STAMAX :
5401 wiphy->rts_threshold;
5402
5403 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5404 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5405 {
5406 hddLog(VOS_TRACE_LEVEL_ERROR,
5407 "%s: Invalid RTS Threshold value %hu",
5408 __func__, rts_threshold);
5409 return -EINVAL;
5410 }
5411
5412 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5413 rts_threshold, ccmCfgSetCallback,
5414 eANI_BOOLEAN_TRUE))
5415 {
5416 hddLog(VOS_TRACE_LEVEL_ERROR,
5417 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5418 __func__, rts_threshold);
5419 return -EIO;
5420 }
5421
5422 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5423 rts_threshold);
5424 }
5425
5426 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5427 {
5428 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5429 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5430 wiphy->frag_threshold;
5431
5432 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5433 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5434 {
5435 hddLog(VOS_TRACE_LEVEL_ERROR,
5436 "%s: Invalid frag_threshold value %hu", __func__,
5437 frag_threshold);
5438 return -EINVAL;
5439 }
5440
5441 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5442 frag_threshold, ccmCfgSetCallback,
5443 eANI_BOOLEAN_TRUE))
5444 {
5445 hddLog(VOS_TRACE_LEVEL_ERROR,
5446 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5447 __func__, frag_threshold);
5448 return -EIO;
5449 }
5450
5451 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5452 frag_threshold);
5453 }
5454
5455 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5456 || (changed & WIPHY_PARAM_RETRY_LONG))
5457 {
5458 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5459 wiphy->retry_short :
5460 wiphy->retry_long;
5461
5462 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5463 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5464 {
5465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5466 __func__, retry_value);
5467 return -EINVAL;
5468 }
5469
5470 if (changed & WIPHY_PARAM_RETRY_SHORT)
5471 {
5472 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5473 retry_value, ccmCfgSetCallback,
5474 eANI_BOOLEAN_TRUE))
5475 {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 "%s: ccmCfgSetInt failed for long retry count %hu",
5478 __func__, retry_value);
5479 return -EIO;
5480 }
5481 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5482 __func__, retry_value);
5483 }
5484 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5485 {
5486 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5487 retry_value, ccmCfgSetCallback,
5488 eANI_BOOLEAN_TRUE))
5489 {
5490 hddLog(VOS_TRACE_LEVEL_ERROR,
5491 "%s: ccmCfgSetInt failed for short retry count %hu",
5492 __func__, retry_value);
5493 return -EIO;
5494 }
5495 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5496 __func__, retry_value);
5497 }
5498 }
5499
5500 return 0;
5501}
5502
5503/*
5504 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5505 * This function is used to set the txpower
5506 */
5507static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5508#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5509 enum tx_power_setting type,
5510#else
5511 enum nl80211_tx_power_setting type,
5512#endif
5513 int dbm)
5514{
5515 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5516 tHalHandle hHal = pHddCtx->hHal;
5517 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5518 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5519
5520 ENTER();
5521
5522 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5523 dbm, ccmCfgSetCallback,
5524 eANI_BOOLEAN_TRUE))
5525 {
5526 hddLog(VOS_TRACE_LEVEL_ERROR,
5527 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5528 return -EIO;
5529 }
5530
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005531 if ( pHddCtx->isLogpInProgress )
5532 {
5533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5534 "%s:LOGP in Progress. Ignore!!!", __func__);
5535 return -EAGAIN;
5536 }
5537
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5539 dbm);
5540
5541 switch(type)
5542 {
5543 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5544 /* Fall through */
5545 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5546 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5547 {
5548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5549 __func__);
5550 return -EIO;
5551 }
5552 break;
5553 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5555 __func__);
5556 return -EOPNOTSUPP;
5557 break;
5558 default:
5559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5560 __func__, type);
5561 return -EIO;
5562 }
5563
5564 return 0;
5565}
5566
5567/*
5568 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5569 * This function is used to read the txpower
5570 */
5571static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5572{
5573
5574 hdd_adapter_t *pAdapter;
5575 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5576
Jeff Johnsone7245742012-09-05 17:12:55 -07005577 ENTER();
5578
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 if (NULL == pHddCtx)
5580 {
5581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5582 *dbm = 0;
5583 return -ENOENT;
5584 }
5585
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005586 if ( pHddCtx->isLogpInProgress )
5587 {
5588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5589 "%s:LOGP in Progress. Ignore!!!", __func__);
5590 return -EAGAIN;
5591 }
5592
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5594 if (NULL == pAdapter)
5595 {
5596 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5597 return -ENOENT;
5598 }
5599
5600 wlan_hdd_get_classAstats(pAdapter);
5601 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5602
Jeff Johnsone7245742012-09-05 17:12:55 -07005603 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 return 0;
5605}
5606
5607static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5608 u8* mac, struct station_info *sinfo)
5609{
5610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5611 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5612 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5613 tANI_U8 rate_flags;
5614
5615 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5616 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5617 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5618
5619 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5620 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5621 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5622 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5623 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5624 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5625 tANI_U16 maxRate = 0;
5626 tANI_U16 myRate;
5627 tANI_U16 currentRate = 0;
5628 tANI_U8 maxSpeedMCS = 0;
5629 tANI_U8 maxMCSIdx = 0;
5630 tANI_U8 rateFlag = 1;
5631 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005632 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005633
Jeff Johnsone7245742012-09-05 17:12:55 -07005634 ENTER();
5635
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5637 (0 == ssidlen))
5638 {
5639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5640 " Invalid ssidlen, %d", __func__, ssidlen);
5641 /*To keep GUI happy*/
5642 return 0;
5643 }
5644
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005645 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5646 {
5647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5648 "%s:LOGP in Progress. Ignore!!!", __func__);
5649 return -EAGAIN;
5650 }
5651
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5653 sinfo->filled |= STATION_INFO_SIGNAL;
5654
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005655 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5657
5658 //convert to the UI units of 100kbps
5659 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5660
5661#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005662 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 -07005663 sinfo->signal,
5664 pCfg->reportMaxLinkSpeed,
5665 myRate,
5666 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005667 (int) pCfg->linkSpeedRssiMid,
5668 (int) pCfg->linkSpeedRssiLow,
5669 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005670#endif //LINKSPEED_DEBUG_ENABLED
5671
5672 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5673 {
5674 // we do not want to necessarily report the current speed
5675 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5676 {
5677 // report the max possible speed
5678 rssidx = 0;
5679 }
5680 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5681 {
5682 // report the max possible speed with RSSI scaling
5683 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5684 {
5685 // report the max possible speed
5686 rssidx = 0;
5687 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005688 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 {
5690 // report middle speed
5691 rssidx = 1;
5692 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005693 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5694 {
5695 // report middle speed
5696 rssidx = 2;
5697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 else
5699 {
5700 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005701 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 }
5703 }
5704 else
5705 {
5706 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5707 hddLog(VOS_TRACE_LEVEL_ERROR,
5708 "%s: Invalid value for reportMaxLinkSpeed: %u",
5709 __func__, pCfg->reportMaxLinkSpeed);
5710 rssidx = 0;
5711 }
5712
5713 maxRate = 0;
5714
5715 /* Get Basic Rate Set */
5716 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5717 for (i = 0; i < ORLeng; i++)
5718 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005719 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 {
5721 /* Validate Rate Set */
5722 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5723 {
5724 currentRate = supported_data_rate[j].supported_rate[rssidx];
5725 break;
5726 }
5727 }
5728 /* Update MAX rate */
5729 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5730 }
5731
5732 /* Get Extended Rate Set */
5733 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5734 for (i = 0; i < ERLeng; i++)
5735 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005736 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 {
5738 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
5739 {
5740 currentRate = supported_data_rate[j].supported_rate[rssidx];
5741 break;
5742 }
5743 }
5744 /* Update MAX rate */
5745 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5746 }
5747
5748 /* Get MCS Rate Set -- but only if we are connected at MCS
5749 rates or if we are always reporting max speed or if we have
5750 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005751 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 {
5753 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
5754 rateFlag = 0;
5755 if (rate_flags & eHAL_TX_RATE_HT40)
5756 {
5757 rateFlag |= 1;
5758 }
5759 if (rate_flags & eHAL_TX_RATE_SGI)
5760 {
5761 rateFlag |= 2;
5762 }
5763
5764 for (i = 0; i < MCSLeng; i++)
5765 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005766 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
5767 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 {
5769 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
5770 {
5771 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
5772 break;
5773 }
5774 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005775 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 {
5777 maxRate = currentRate;
5778 maxSpeedMCS = 1;
5779 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
5780 }
5781 }
5782 }
5783
5784 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005785 if (((maxRate < myRate) && (0 == rssidx)) ||
5786 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 {
5788 maxRate = myRate;
5789 if (rate_flags & eHAL_TX_RATE_LEGACY)
5790 {
5791 maxSpeedMCS = 0;
5792 }
5793 else
5794 {
5795 maxSpeedMCS = 1;
5796 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5797 }
5798 }
5799
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005800 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 {
5802 sinfo->txrate.legacy = maxRate;
5803#ifdef LINKSPEED_DEBUG_ENABLED
5804 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
5805#endif //LINKSPEED_DEBUG_ENABLED
5806 }
5807 else
5808 {
5809 sinfo->txrate.mcs = maxMCSIdx;
5810 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5811 if (rate_flags & eHAL_TX_RATE_SGI)
5812 {
5813 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5814 }
5815 if (rate_flags & eHAL_TX_RATE_HT40)
5816 {
5817 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5818 }
5819#ifdef LINKSPEED_DEBUG_ENABLED
5820 pr_info("Reporting MCS rate %d flags %x\n",
5821 sinfo->txrate.mcs,
5822 sinfo->txrate.flags );
5823#endif //LINKSPEED_DEBUG_ENABLED
5824 }
5825 }
5826 else
5827 {
5828 // report current rate instead of max rate
5829
5830 if (rate_flags & eHAL_TX_RATE_LEGACY)
5831 {
5832 //provide to the UI in units of 100kbps
5833 sinfo->txrate.legacy = myRate;
5834#ifdef LINKSPEED_DEBUG_ENABLED
5835 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
5836#endif //LINKSPEED_DEBUG_ENABLED
5837 }
5838 else
5839 {
5840 //must be MCS
5841 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
5842 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
5843 if (rate_flags & eHAL_TX_RATE_SGI)
5844 {
5845 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
5846 }
5847 if (rate_flags & eHAL_TX_RATE_HT40)
5848 {
5849 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
5850 }
5851#ifdef LINKSPEED_DEBUG_ENABLED
5852 pr_info("Reporting actual MCS rate %d flags %x\n",
5853 sinfo->txrate.mcs,
5854 sinfo->txrate.flags );
5855#endif //LINKSPEED_DEBUG_ENABLED
5856 }
5857 }
5858 sinfo->filled |= STATION_INFO_TX_BITRATE;
5859
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005860 sinfo->tx_packets =
5861 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
5862 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
5863 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
5864 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
5865
5866 sinfo->tx_retries =
5867 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
5868 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
5869 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
5870 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
5871
5872 sinfo->tx_failed =
5873 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
5874 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
5875 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
5876 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
5877
5878 sinfo->filled |=
5879 STATION_INFO_TX_PACKETS |
5880 STATION_INFO_TX_RETRIES |
5881 STATION_INFO_TX_FAILED;
5882
5883 EXIT();
5884 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005885}
5886
5887static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
5888 struct net_device *dev, bool mode, v_SINT_t timeout)
5889{
5890 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5891 VOS_STATUS vos_status;
5892
Jeff Johnsone7245742012-09-05 17:12:55 -07005893 ENTER();
5894
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 if (NULL == pAdapter)
5896 {
5897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
5898 return -ENODEV;
5899 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005900 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5901 {
5902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5903 "%s:LOGP in Progress. Ignore!!!", __func__);
5904 return -EAGAIN;
5905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005906
5907 /**The get power cmd from the supplicant gets updated by the nl only
5908 *on successful execution of the function call
5909 *we are oppositely mapped w.r.t mode in the driver
5910 **/
5911 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
5912
Jeff Johnsone7245742012-09-05 17:12:55 -07005913 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 if (VOS_STATUS_E_FAILURE == vos_status)
5915 {
5916 return -EINVAL;
5917 }
5918 return 0;
5919}
5920
5921
5922#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5923static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
5924 struct net_device *netdev,
5925 u8 key_index)
5926{
Jeff Johnsone7245742012-09-05 17:12:55 -07005927 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 return 0;
5929}
5930#endif //LINUX_VERSION_CODE
5931
5932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5933static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5934 struct net_device *dev,
5935 struct ieee80211_txq_params *params)
5936{
Jeff Johnsone7245742012-09-05 17:12:55 -07005937 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 return 0;
5939}
5940#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5941static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
5942 struct ieee80211_txq_params *params)
5943{
Jeff Johnsone7245742012-09-05 17:12:55 -07005944 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 return 0;
5946}
5947#endif //LINUX_VERSION_CODE
5948
5949static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
5950 struct net_device *dev, u8 *mac)
5951{
5952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5953
Jeff Johnsone7245742012-09-05 17:12:55 -07005954 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
5956 {
5957 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
5958 return -EINVAL;
5959 }
5960
5961 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
5962 {
5963 hddLog( LOGE,
5964 "%s: Wlan Load/Unload is in progress", __func__);
5965 return -EBUSY;
5966 }
5967
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005968 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5969 {
5970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5971 "%s:LOGP in Progress. Ignore!!!", __func__);
5972 return -EAGAIN;
5973 }
5974
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
5976#ifdef WLAN_FEATURE_P2P
5977 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5978#endif
5979 )
5980 {
5981 if( NULL == mac )
5982 {
5983 v_U16_t i;
5984 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
5985 {
5986 if(pAdapter->aStaInfo[i].isUsed)
5987 {
5988 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
5989 hddLog(VOS_TRACE_LEVEL_INFO,
5990 "%s: Delete STA with MAC::"
5991 "%02x:%02x:%02x:%02x:%02x:%02x",
5992 __func__,
5993 macAddr[0], macAddr[1], macAddr[2],
5994 macAddr[3], macAddr[4], macAddr[5]);
5995 hdd_softap_sta_deauth(pAdapter, macAddr);
5996 }
5997 }
5998 }
5999 else
6000 {
6001 hddLog(VOS_TRACE_LEVEL_INFO,
6002 "%s: Delete STA with MAC::"
6003 "%02x:%02x:%02x:%02x:%02x:%02x",
6004 __func__,
6005 mac[0], mac[1], mac[2],
6006 mac[3], mac[4], mac[5]);
6007 hdd_softap_sta_deauth(pAdapter, mac);
6008 }
6009 }
6010
6011 EXIT();
6012
6013 return 0;
6014}
6015
6016static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6017 struct net_device *dev, u8 *mac, struct station_parameters *params)
6018{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006019#ifdef FEATURE_WLAN_TDLS
6020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6021 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6022 u32 mask, set;
6023 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006024 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006025
6026 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6027 {
6028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6029 "Invalid arguments");
6030 return -EINVAL;
6031 }
6032
6033 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6034 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6035 {
6036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6037 "TDLS Disabled in INI OR not enabled in FW.\
6038 Cannot process TDLS commands \n");
6039 return -ENOTSUPP;
6040 }
6041
6042 mask = params->sta_flags_mask;
6043
6044 set = params->sta_flags_set;
6045
6046
6047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6048 "Add Station Request Mask = 0x%x set = 0x%x\n", mask, set);
6049
6050 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6051 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6053 "Add TDLS peer");
6054
6055
6056 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6057 pAdapter->sessionId, mac);
6058
6059 if (VOS_STATUS_SUCCESS != status) {
6060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6061 "%s: sme_AddTdlsPeerSta failed!", __func__);
6062 }
6063 }
6064 }
6065#endif
6066
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 return 0;
6068}
6069
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006070
6071#ifdef FEATURE_WLAN_LFR
6072static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006073 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006074{
6075#define MAX_PMKSAIDS_IN_CACHE 8
6076 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006077 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006078 tANI_U32 j=0;
6079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6080 tHalHandle halHandle;
6081 eHalStatus result;
6082 tANI_U8 BSSIDMatched = 0;
6083
Jeff Johnsone7245742012-09-05 17:12:55 -07006084 ENTER();
6085
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006086 // Validate pAdapter
6087 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6088 {
6089 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6090 return -EINVAL;
6091 }
6092
6093 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6094 {
6095 hddLog( LOGE,
6096 "%s: Wlan Load/Unload is in progress", __func__);
6097 return -EBUSY;
6098 }
6099
6100 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6101 {
6102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6103 "%s:LOGP in Progress. Ignore!!!", __func__);
6104 return -EAGAIN;
6105 }
6106
6107 // Retrieve halHandle
6108 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6109
6110 for (j = 0; j < i; j++)
6111 {
6112 if(vos_mem_compare(PMKIDCache[j].BSSID,
6113 pmksa->bssid, WNI_CFG_BSSID_LEN))
6114 {
6115 /* BSSID matched previous entry. Overwrite it. */
6116 BSSIDMatched = 1;
6117 vos_mem_copy(PMKIDCache[j].BSSID,
6118 pmksa->bssid, WNI_CFG_BSSID_LEN);
6119 vos_mem_copy(PMKIDCache[j].PMKID,
6120 pmksa->pmkid,
6121 CSR_RSN_PMKID_SIZE);
6122 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006123 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006124 dump_bssid(pmksa->bssid);
6125 dump_pmkid(halHandle, pmksa->pmkid);
6126 break;
6127 }
6128 }
6129
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006130 /* Check we compared all entries,if then take the first slot now */
6131 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6132
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006133 if (!BSSIDMatched)
6134 {
6135 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6136 vos_mem_copy(PMKIDCache[i].BSSID,
6137 pmksa->bssid, ETHER_ADDR_LEN);
6138 vos_mem_copy(PMKIDCache[i].PMKID,
6139 pmksa->pmkid,
6140 CSR_RSN_PMKID_SIZE);
6141 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006142 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006143 dump_bssid(pmksa->bssid);
6144 dump_pmkid(halHandle, pmksa->pmkid);
6145 // Increment the HDD Local Cache index
6146 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6147 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6148 }
6149
6150
6151 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6152 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006153 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006154 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006155 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006156 // Finally set the PMKSA ID Cache in CSR
6157 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6158 PMKIDCache,
6159 i );
6160 return 0;
6161}
6162
6163
6164static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006165 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006166{
Jeff Johnsone7245742012-09-05 17:12:55 -07006167 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006168 // TODO: Implement this later.
6169 return 0;
6170}
6171
6172static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6173{
Jeff Johnsone7245742012-09-05 17:12:55 -07006174 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006175 // TODO: Implement this later.
6176 return 0;
6177}
6178#endif
6179
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006180#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6181static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6182 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6183{
6184 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6185 hdd_station_ctx_t *pHddStaCtx;
6186
6187 if (NULL == pAdapter)
6188 {
6189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6190 return -ENODEV;
6191 }
6192
6193 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6194
6195 // Added for debug on reception of Re-assoc Req.
6196 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6197 {
6198 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6199 ftie->ie_len);
6200 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6201 }
6202
6203#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6204 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6205 ftie->ie_len);
6206#endif
6207
6208 // Pass the received FT IEs to SME
6209 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6210 ftie->ie_len);
6211 return 0;
6212}
6213#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006214
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006215#ifdef FEATURE_WLAN_TDLS
6216static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6217 u8 *peer, u8 action_code, u8 dialog_token,
6218 u16 status_code, const u8 *buf, size_t len)
6219{
6220
6221 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6222 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6223 u8 *buf_1;
6224 size_t len_1 = len;
6225 u8 peerMac[6];
6226 VOS_STATUS status;
6227
6228 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6229 {
6230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6231 "Invalid arguments");
6232 return -EINVAL;
6233 }
6234
6235 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6236 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6237 {
6238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6239 "TDLS Disabled in INI OR not enabled in FW.\
6240 Cannot process TDLS commands \n");
6241 return -ENOTSUPP;
6242 }
6243 vos_mem_copy( peerMac, peer, 6);
6244
6245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6246 "Request to send TDLS management: action = %d, status = %d, \
6247 len = %d", action_code, status_code, len);
6248
6249 buf_1 = vos_mem_malloc(len);
6250 if(buf_1 == NULL) {
6251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6252 "%s: malloc failed!", __func__);
6253 return -ENOMEM;
6254 }
6255 vos_mem_copy(buf_1, buf, len);
6256
6257 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6258 peerMac, action_code, dialog_token, status_code, buf_1, len_1);
6259
6260 if (VOS_STATUS_SUCCESS != status) {
6261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6262 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6263 }
6264
6265 vos_mem_free(buf_1);
6266
6267 return 0;
6268}
6269
6270static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6271 u8 *peer, enum nl80211_tdls_operation oper)
6272{
6273 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6274 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6275
6276 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6277 {
6278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 "Invalid arguments");
6280 return -EINVAL;
6281 }
6282
6283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6284 "Request for TDLS oper: %d", (int)oper);
6285
6286 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6287 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6288 {
6289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6290 "TDLS Disabled in INI OR not enabled in FW.\
6291 Cannot process TDLS commands \n");
6292 return -ENOTSUPP;
6293 }
6294
6295 switch (oper) {
6296 case NL80211_TDLS_ENABLE_LINK:
6297 {
6298 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
6299 v_U8_t my_peer[6];
6300 v_U8_t ucSTAId;
6301 VOS_STATUS status;
6302
6303 if (peer) {
6304 vos_mem_copy(my_peer, peer, 6);
6305 ucSTAId = wlan_hdd_findTdlsPeer(my_peer);
6306
6307 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6308 "%s: set key for peer %2x:%2x:%2x:%2x:%2x:%2x",
6309 __func__, peer[0], peer[1],
6310 peer[2], peer[3],
6311 peer[4], peer[5] );
6312
6313 if (-1 == ucSTAId ) {
6314 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan_hdd_findTdlsPeer failed" );
6315 return 0;
6316 }
6317
6318 status = WLANTL_ChangeSTAState( pVosContext, ucSTAId,
6319 WLANTL_STA_AUTHENTICATED );
6320
6321 if (0 != status) {
6322 hddLog(VOS_TRACE_LEVEL_ERROR,
6323 "%s: WLANTL_ChangeSTAState failed, returned %d",
6324 __func__, status);
6325 return status;
6326 }
6327 } else {
6328 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6329 }
6330 }
6331 break;
6332 case NL80211_TDLS_DISABLE_LINK:
6333 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6334 pAdapter->sessionId, peer );
6335 return 0;
6336 case NL80211_TDLS_TEARDOWN:
6337 case NL80211_TDLS_SETUP:
6338 case NL80211_TDLS_DISCOVERY_REQ:
6339 /* We don't support in-driver setup/teardown/discovery */
6340 return -ENOTSUPP;
6341 default:
6342 return -ENOTSUPP;
6343 }
6344 return 0;
6345}
6346#endif
6347
Jeff Johnson295189b2012-06-20 16:38:30 -07006348/* cfg80211_ops */
6349static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6350{
6351 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6352 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6353 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6354 .change_station = wlan_hdd_change_station,
6355#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6356 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6357 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6358 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006359#else
6360 .start_ap = wlan_hdd_cfg80211_start_ap,
6361 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6362 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006363#endif
6364 .change_bss = wlan_hdd_cfg80211_change_bss,
6365 .add_key = wlan_hdd_cfg80211_add_key,
6366 .get_key = wlan_hdd_cfg80211_get_key,
6367 .del_key = wlan_hdd_cfg80211_del_key,
6368 .set_default_key = wlan_hdd_cfg80211_set_default_key,
6369 .set_channel = wlan_hdd_cfg80211_set_channel,
6370 .scan = wlan_hdd_cfg80211_scan,
6371 .connect = wlan_hdd_cfg80211_connect,
6372 .disconnect = wlan_hdd_cfg80211_disconnect,
6373 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6374 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6375 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6376 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6377 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6378#ifdef WLAN_FEATURE_P2P
6379 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6380 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6381 .mgmt_tx = wlan_hdd_action,
6382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6383 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6384 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6385 .set_txq_params = wlan_hdd_set_txq_params,
6386#endif
6387#endif
6388 .get_station = wlan_hdd_cfg80211_get_station,
6389 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6390 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006391 .add_station = wlan_hdd_cfg80211_add_station,
6392#ifdef FEATURE_WLAN_LFR
6393 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6394 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6395 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6396#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006397#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6398 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6399#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006400#ifdef FEATURE_WLAN_TDLS
6401 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6402 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6403#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006404};
6405
6406#endif // CONFIG_CFG80211