blob: d48a98df4b8f76abc5a3f7b4572b72bdfbf18abd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**========================================================================
43
44 \file wlan_hdd_cfg80211.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 21/12/09 Ashwani Created module.
69
70 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
71 Ganesh K
72 ==========================================================================*/
73
74#ifdef CONFIG_CFG80211
75
76#include <linux/version.h>
77#include <linux/module.h>
78#include <linux/kernel.h>
79#include <linux/init.h>
80#include <linux/wireless.h>
81#include <wlan_hdd_includes.h>
82#include <net/arp.h>
83#include <net/cfg80211.h>
84#include <linux/wireless.h>
85#include <wlan_hdd_wowl.h>
86#include <aniGlobal.h>
87#include "ccmApi.h"
88#include "sirParams.h"
89#include "dot11f.h"
90#include "wlan_hdd_assoc.h"
91#include "wlan_hdd_wext.h"
92#include "sme_Api.h"
93#include "wlan_hdd_p2p.h"
94#include "wlan_hdd_cfg80211.h"
95#include "wlan_hdd_hostapd.h"
96#include "sapInternal.h"
97#include "wlan_hdd_softap_tx_rx.h"
98#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053099#include "wlan_hdd_assoc.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#ifdef WLAN_BTAMP_FEATURE
101#include "bap_hdd_misc.h"
102#endif
103#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800104#ifdef FEATURE_WLAN_TDLS
105#include "wlan_hdd_tdls.h"
106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define g_mode_rates_size (12)
109#define a_mode_rates_size (8)
110#define FREQ_BASE_80211G (2407)
111#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700112#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
114 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
115
116#define HDD2GHZCHAN(freq, chan, flag) { \
117 .band = IEEE80211_BAND_2GHZ, \
118 .center_freq = (freq), \
119 .hw_value = (chan),\
120 .flags = (flag), \
121 .max_antenna_gain = 0 ,\
122 .max_power = 30, \
123}
124
125#define HDD5GHZCHAN(freq, chan, flag) { \
126 .band = IEEE80211_BAND_5GHZ, \
127 .center_freq = (freq), \
128 .hw_value = (chan),\
129 .flags = (flag), \
130 .max_antenna_gain = 0 ,\
131 .max_power = 30, \
132}
133
134#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
135{\
136 .bitrate = rate, \
137 .hw_value = rate_id, \
138 .flags = flag, \
139}
140
Lee Hoonkic1262f22013-01-24 21:59:00 -0800141#ifndef WLAN_FEATURE_TDLS_DEBUG
142#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
143#else
144#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
145#endif
146
Jeff Johnson295189b2012-06-20 16:38:30 -0700147static const u32 hdd_cipher_suites[] =
148{
149 WLAN_CIPHER_SUITE_WEP40,
150 WLAN_CIPHER_SUITE_WEP104,
151 WLAN_CIPHER_SUITE_TKIP,
152#ifdef FEATURE_WLAN_CCX
153#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
154 WLAN_CIPHER_SUITE_KRK,
155 WLAN_CIPHER_SUITE_CCMP,
156#else
157 WLAN_CIPHER_SUITE_CCMP,
158#endif
159#ifdef FEATURE_WLAN_WAPI
160 WLAN_CIPHER_SUITE_SMS4,
161#endif
162};
163
164static inline int is_broadcast_ether_addr(const u8 *addr)
165{
166 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
167 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
168}
169
170static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
171{
172 HDD2GHZCHAN(2412, 1, 0) ,
173 HDD2GHZCHAN(2417, 2, 0) ,
174 HDD2GHZCHAN(2422, 3, 0) ,
175 HDD2GHZCHAN(2427, 4, 0) ,
176 HDD2GHZCHAN(2432, 5, 0) ,
177 HDD2GHZCHAN(2437, 6, 0) ,
178 HDD2GHZCHAN(2442, 7, 0) ,
179 HDD2GHZCHAN(2447, 8, 0) ,
180 HDD2GHZCHAN(2452, 9, 0) ,
181 HDD2GHZCHAN(2457, 10, 0) ,
182 HDD2GHZCHAN(2462, 11, 0) ,
183 HDD2GHZCHAN(2467, 12, 0) ,
184 HDD2GHZCHAN(2472, 13, 0) ,
185 HDD2GHZCHAN(2484, 14, 0) ,
186};
187
188#ifdef WLAN_FEATURE_P2P
189static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
190{
191 HDD2GHZCHAN(2412, 1, 0) ,
192 HDD2GHZCHAN(2437, 6, 0) ,
193 HDD2GHZCHAN(2462, 11, 0) ,
194};
195#endif
196
197static struct ieee80211_channel hdd_channels_5_GHZ[] =
198{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700199 HDD5GHZCHAN(4920, 240, 0) ,
200 HDD5GHZCHAN(4940, 244, 0) ,
201 HDD5GHZCHAN(4960, 248, 0) ,
202 HDD5GHZCHAN(4980, 252, 0) ,
203 HDD5GHZCHAN(5040, 208, 0) ,
204 HDD5GHZCHAN(5060, 212, 0) ,
205 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 HDD5GHZCHAN(5180, 36, 0) ,
207 HDD5GHZCHAN(5200, 40, 0) ,
208 HDD5GHZCHAN(5220, 44, 0) ,
209 HDD5GHZCHAN(5240, 48, 0) ,
210 HDD5GHZCHAN(5260, 52, 0) ,
211 HDD5GHZCHAN(5280, 56, 0) ,
212 HDD5GHZCHAN(5300, 60, 0) ,
213 HDD5GHZCHAN(5320, 64, 0) ,
214 HDD5GHZCHAN(5500,100, 0) ,
215 HDD5GHZCHAN(5520,104, 0) ,
216 HDD5GHZCHAN(5540,108, 0) ,
217 HDD5GHZCHAN(5560,112, 0) ,
218 HDD5GHZCHAN(5580,116, 0) ,
219 HDD5GHZCHAN(5600,120, 0) ,
220 HDD5GHZCHAN(5620,124, 0) ,
221 HDD5GHZCHAN(5640,128, 0) ,
222 HDD5GHZCHAN(5660,132, 0) ,
223 HDD5GHZCHAN(5680,136, 0) ,
224 HDD5GHZCHAN(5700,140, 0) ,
225 HDD5GHZCHAN(5745,149, 0) ,
226 HDD5GHZCHAN(5765,153, 0) ,
227 HDD5GHZCHAN(5785,157, 0) ,
228 HDD5GHZCHAN(5805,161, 0) ,
229 HDD5GHZCHAN(5825,165, 0) ,
230};
231
232static struct ieee80211_rate g_mode_rates[] =
233{
234 HDD_G_MODE_RATETAB(10, 0x1, 0),
235 HDD_G_MODE_RATETAB(20, 0x2, 0),
236 HDD_G_MODE_RATETAB(55, 0x4, 0),
237 HDD_G_MODE_RATETAB(110, 0x8, 0),
238 HDD_G_MODE_RATETAB(60, 0x10, 0),
239 HDD_G_MODE_RATETAB(90, 0x20, 0),
240 HDD_G_MODE_RATETAB(120, 0x40, 0),
241 HDD_G_MODE_RATETAB(180, 0x80, 0),
242 HDD_G_MODE_RATETAB(240, 0x100, 0),
243 HDD_G_MODE_RATETAB(360, 0x200, 0),
244 HDD_G_MODE_RATETAB(480, 0x400, 0),
245 HDD_G_MODE_RATETAB(540, 0x800, 0),
246};
247
248static struct ieee80211_rate a_mode_rates[] =
249{
250 HDD_G_MODE_RATETAB(60, 0x10, 0),
251 HDD_G_MODE_RATETAB(90, 0x20, 0),
252 HDD_G_MODE_RATETAB(120, 0x40, 0),
253 HDD_G_MODE_RATETAB(180, 0x80, 0),
254 HDD_G_MODE_RATETAB(240, 0x100, 0),
255 HDD_G_MODE_RATETAB(360, 0x200, 0),
256 HDD_G_MODE_RATETAB(480, 0x400, 0),
257 HDD_G_MODE_RATETAB(540, 0x800, 0),
258};
259
260static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
261{
262 .channels = hdd_channels_2_4_GHZ,
263 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
264 .band = IEEE80211_BAND_2GHZ,
265 .bitrates = g_mode_rates,
266 .n_bitrates = g_mode_rates_size,
267 .ht_cap.ht_supported = 1,
268 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
269 | IEEE80211_HT_CAP_GRN_FLD
270 | IEEE80211_HT_CAP_DSSSCCK40
271 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
272 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
273 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
274 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
275 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
276 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
277};
278
279#ifdef WLAN_FEATURE_P2P
280static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
281{
282 .channels = hdd_social_channels_2_4_GHZ,
283 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
284 .band = IEEE80211_BAND_2GHZ,
285 .bitrates = g_mode_rates,
286 .n_bitrates = g_mode_rates_size,
287 .ht_cap.ht_supported = 1,
288 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
289 | IEEE80211_HT_CAP_GRN_FLD
290 | IEEE80211_HT_CAP_DSSSCCK40
291 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
292 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
293 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
294 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
295 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
296 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
297};
298#endif
299
300static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
301{
302 .channels = hdd_channels_5_GHZ,
303 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
304 .band = IEEE80211_BAND_5GHZ,
305 .bitrates = a_mode_rates,
306 .n_bitrates = a_mode_rates_size,
307 .ht_cap.ht_supported = 1,
308 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
309 | IEEE80211_HT_CAP_GRN_FLD
310 | IEEE80211_HT_CAP_DSSSCCK40
311 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
312 | IEEE80211_HT_CAP_SGI_40
313 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
314 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
315 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
316 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
317 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
318 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
319};
320
321/* This structure contain information what kind of frame are expected in
322 TX/RX direction for each kind of interface */
323static const struct ieee80211_txrx_stypes
324wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
325 [NL80211_IFTYPE_STATION] = {
326 .tx = 0xffff,
327 .rx = BIT(SIR_MAC_MGMT_ACTION) |
328 BIT(SIR_MAC_MGMT_PROBE_REQ),
329 },
330 [NL80211_IFTYPE_AP] = {
331 .tx = 0xffff,
332 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
333 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_PROBE_REQ) |
335 BIT(SIR_MAC_MGMT_DISASSOC) |
336 BIT(SIR_MAC_MGMT_AUTH) |
337 BIT(SIR_MAC_MGMT_DEAUTH) |
338 BIT(SIR_MAC_MGMT_ACTION),
339 },
340#ifdef WLAN_FEATURE_P2P
341 [NL80211_IFTYPE_P2P_CLIENT] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ACTION) |
344 BIT(SIR_MAC_MGMT_PROBE_REQ),
345 },
346 [NL80211_IFTYPE_P2P_GO] = {
347 /* This is also same as for SoftAP */
348 .tx = 0xffff,
349 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
350 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ) |
352 BIT(SIR_MAC_MGMT_DISASSOC) |
353 BIT(SIR_MAC_MGMT_AUTH) |
354 BIT(SIR_MAC_MGMT_DEAUTH) |
355 BIT(SIR_MAC_MGMT_ACTION),
356 },
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800357#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700358};
359
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800360#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
361#ifdef WLAN_FEATURE_P2P
362static const struct ieee80211_iface_limit
363wlan_hdd_iface_limit[] = {
364 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800365 /* max = 3 ; Our driver create two interfaces during driver init
366 * wlan0 and p2p0 interfaces. p2p0 is considered as station
367 * interface until a group is formed. In JB architecture, once the
368 * group is formed, interface type of p2p0 is changed to P2P GO or
369 * Client.
370 * When supplicant remove the group, it first issue a set interface
371 * cmd to change the mode back to Station. In JB this works fine as
372 * we advertize two station type interface during driver init.
373 * Some vendors create separate interface for P2P GO/Client,
374 * after group formation(Third one). But while group remove
375 * supplicant first tries to change the mode(3rd interface) to STATION
376 * But as we advertized only two sta type interfaces nl80211 was
377 * returning error for the third one which was leading to failure in
378 * delete interface. Ideally while removing the group, supplicant
379 * should not try to change the 3rd interface mode to Station type.
380 * Till we get a fix in wpa_supplicant, we advertize max STA
381 * interface type to 3
382 */
383 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384 .types = BIT(NL80211_IFTYPE_STATION),
385 },
386 {
387 .max = 1,
388 .types = BIT(NL80211_IFTYPE_AP),
389 },
390 {
391 .max = 1,
392 .types = BIT(NL80211_IFTYPE_P2P_GO) |
393 BIT(NL80211_IFTYPE_P2P_CLIENT),
394 },
395};
396
397/* By default, only single channel concurrency is allowed */
398static struct ieee80211_iface_combination
399wlan_hdd_iface_combination = {
400 .limits = wlan_hdd_iface_limit,
401 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800402 /*
403 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
404 * and p2p0 interfaces during driver init
405 * Some vendors create separate interface for P2P operations.
406 * wlan0: STA interface
407 * p2p0: P2P Device interface, action frames goes
408 * through this interface.
409 * p2p-xx: P2P interface, After GO negotiation this interface is
410 * created for p2p operations(GO/CLIENT interface).
411 */
412 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800413 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
414 .beacon_int_infra_match = false,
415};
416#endif
417#endif
418
Jeff Johnson295189b2012-06-20 16:38:30 -0700419static struct cfg80211_ops wlan_hdd_cfg80211_ops;
420
421/* Data rate 100KBPS based on IE Index */
422struct index_data_rate_type
423{
424 v_U8_t beacon_rate_index;
425 v_U16_t supported_rate[4];
426};
427
428/* 11B, 11G Rate table include Basic rate and Extended rate
429 The IDX field is the rate index
430 The HI field is the rate when RSSI is strong or being ignored
431 (in this case we report actual rate)
432 The MID field is the rate when RSSI is moderate
433 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
434 The LO field is the rate when RSSI is low
435 (in this case we don't report rates, actual current rate used)
436 */
437static const struct
438{
439 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700440 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700441} supported_data_rate[] =
442{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700443/* IDX HI HM LM LO (RSSI-based index */
444 {2, { 10, 10, 10, 0}},
445 {4, { 20, 20, 10, 0}},
446 {11, { 55, 20, 10, 0}},
447 {12, { 60, 55, 20, 0}},
448 {18, { 90, 55, 20, 0}},
449 {22, {110, 55, 20, 0}},
450 {24, {120, 90, 60, 0}},
451 {36, {180, 120, 60, 0}},
452 {44, {220, 180, 60, 0}},
453 {48, {240, 180, 90, 0}},
454 {66, {330, 180, 90, 0}},
455 {72, {360, 240, 90, 0}},
456 {96, {480, 240, 120, 0}},
457 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700458};
459
460/* MCS Based rate table */
461static struct index_data_rate_type supported_mcs_rate[] =
462{
463/* MCS L20 L40 S20 S40 */
464 {0, {65, 135, 72, 150}},
465 {1, {130, 270, 144, 300}},
466 {2, {195, 405, 217, 450}},
467 {3, {260, 540, 289, 600}},
468 {4, {390, 810, 433, 900}},
469 {5, {520, 1080, 578, 1200}},
470 {6, {585, 1215, 650, 1350}},
471 {7, {650, 1350, 722, 1500}}
472};
473
474extern struct net_device_ops net_ops_struct;
475
476/*
477 * FUNCTION: wlan_hdd_cfg80211_init
478 * This function is called by hdd_wlan_startup()
479 * during initialization.
480 * This function is used to initialize and register wiphy structure.
481 */
482struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
483{
484 struct wiphy *wiphy;
485 ENTER();
486
487 /*
488 * Create wiphy device
489 */
490 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
491
492 if (!wiphy)
493 {
494 /* Print error and jump into err label and free the memory */
495 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
496 return NULL;
497 }
498
499 return wiphy;
500}
501
502/*
503 * FUNCTION: wlan_hdd_cfg80211_update_band
504 * This function is called from the supplicant through a
505 * private ioctl to change the band value
506 */
507int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
508{
Jeff Johnsone7245742012-09-05 17:12:55 -0700509 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700510 switch(eBand)
511 {
512 case eCSR_BAND_24:
513 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
514 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
515 break;
516 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700517#ifdef WLAN_FEATURE_P2P
518 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
519#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700520 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700521#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700522 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
523 break;
524 case eCSR_BAND_ALL:
525 default:
526 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
527 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
528 }
529 return 0;
530}
531/*
532 * FUNCTION: wlan_hdd_cfg80211_init
533 * This function is called by hdd_wlan_startup()
534 * during initialization.
535 * This function is used to initialize and register wiphy structure.
536 */
537int wlan_hdd_cfg80211_register(struct device *dev,
538 struct wiphy *wiphy,
539 hdd_config_t *pCfg
540 )
541{
Jeff Johnsone7245742012-09-05 17:12:55 -0700542 ENTER();
543
Jeff Johnson295189b2012-06-20 16:38:30 -0700544 /* Now bind the underlying wlan device with wiphy */
545 set_wiphy_dev(wiphy, dev);
546
547 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
548
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700549 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700550
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700552 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
553 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
554 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700555 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700556#endif
James Zmuda77fb5ae2013-01-29 08:00:17 -0800557#ifdef FEATURE_WLAN_LFR
558 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
559#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800560#ifdef FEATURE_WLAN_TDLS
561 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
562 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
563#endif
564
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700565 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
566 driver can still register regulatory callback and
567 it will get CRDA setting in wiphy->band[], but
568 driver need to determine what to do with both
569 regulatory settings */
570 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700571
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 wiphy->max_scan_ssids = MAX_SCAN_SSID;
573
574 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
575
576 /* Supports STATION & AD-HOC modes right now */
577 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
578 | BIT(NL80211_IFTYPE_ADHOC)
579#ifdef WLAN_FEATURE_P2P
580 | BIT(NL80211_IFTYPE_P2P_CLIENT)
581 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 | BIT(NL80211_IFTYPE_AP);
584
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800585#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
586#ifdef WLAN_FEATURE_P2P
587 if( pCfg->enableMCC )
588 {
589 /* Currently, supports up to two channels */
590 wlan_hdd_iface_combination.num_different_channels = 2;
591
592 if( !pCfg->allowMCCGODiffBI )
593 wlan_hdd_iface_combination.beacon_int_infra_match = true;
594
595 }
596 wiphy->iface_combinations = &wlan_hdd_iface_combination;
597 wiphy->n_iface_combinations = 1;
598#endif
599#endif
600
Jeff Johnson295189b2012-06-20 16:38:30 -0700601 /* Before registering we need to update the ht capabilitied based
602 * on ini values*/
603 if( !pCfg->ShortGI20MhzEnable )
604 {
605 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
606 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
607 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
608 }
609
610 if( !pCfg->ShortGI40MhzEnable )
611 {
612 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
613 }
614
615 if( !pCfg->nChannelBondingMode5GHz )
616 {
617 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
618 }
619
620 /*Initialize band capability*/
621 switch(pCfg->nBandCapability)
622 {
623 case eCSR_BAND_24:
624 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
625 break;
626 case eCSR_BAND_5G:
627#ifdef WLAN_FEATURE_P2P
628 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
629#endif
630 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
631 break;
632 case eCSR_BAND_ALL:
633 default:
634 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
635 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
636 }
637 /*Initialise the supported cipher suite details*/
638 wiphy->cipher_suites = hdd_cipher_suites;
639 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
640
641 /*signal strength in mBm (100*dBm) */
642 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
643
644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
645#ifdef WLAN_FEATURE_P2P
646 wiphy->max_remain_on_channel_duration = 1000;
647#endif
648#endif
649
650 /* Register our wiphy dev with cfg80211 */
651 if (0 > wiphy_register(wiphy))
652 {
653 /* print eror */
654 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
655 return -EIO;
656 }
657
658 EXIT();
659 return 0;
660}
661
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700662/* In this function we will try to get default country code from crda.
663 If the gCrdaDefaultCountryCode is configured in ini file,
664 we will try to call user space crda to get the regulatory settings for
665 that country. We will timeout if we can't get it from crda.
666 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
667*/
668int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
669{
670 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
671 if (memcmp(pCfg->crdaDefaultCountryCode,
672 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
673 {
674 init_completion(&pHddCtx->driver_crda_req);
675 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
676 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
677 CRDA_WAIT_TIME);
678 }
679 return 0;
680}
681
Jeff Johnson295189b2012-06-20 16:38:30 -0700682/* In this function we will do all post VOS start initialization.
683 In this function we will register for all frame in which supplicant
684 is interested.
685*/
686void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
687{
688#ifdef WLAN_FEATURE_P2P
689 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
690 /* Register for all P2P action, public action etc frames */
691 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
692
Jeff Johnsone7245742012-09-05 17:12:55 -0700693 ENTER();
694
Jeff Johnson295189b2012-06-20 16:38:30 -0700695 /* Right now we are registering these frame when driver is getting
696 initialized. Once we will move to 2.6.37 kernel, in which we have
697 frame register ops, we will move this code as a part of that */
698 /* GAS Initial Request */
699 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
700 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
701
702 /* GAS Initial Response */
703 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
704 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
705
706 /* GAS Comeback Request */
707 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
708 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
709
710 /* GAS Comeback Response */
711 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
712 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
713
714 /* P2P Public Action */
715 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
716 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
717 P2P_PUBLIC_ACTION_FRAME_SIZE );
718
719 /* P2P Action */
720 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
721 (v_U8_t*)P2P_ACTION_FRAME,
722 P2P_ACTION_FRAME_SIZE );
723#endif /* WLAN_FEATURE_P2P */
724}
725
726void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
727{
728#ifdef WLAN_FEATURE_P2P
729 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
730 /* Register for all P2P action, public action etc frames */
731 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
732
Jeff Johnsone7245742012-09-05 17:12:55 -0700733 ENTER();
734
Jeff Johnson295189b2012-06-20 16:38:30 -0700735 /* Right now we are registering these frame when driver is getting
736 initialized. Once we will move to 2.6.37 kernel, in which we have
737 frame register ops, we will move this code as a part of that */
738 /* GAS Initial Request */
739
740 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
741 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
742
743 /* GAS Initial Response */
744 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
745 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
746
747 /* GAS Comeback Request */
748 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
749 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
750
751 /* GAS Comeback Response */
752 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
753 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
754
755 /* P2P Public Action */
756 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
757 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
758 P2P_PUBLIC_ACTION_FRAME_SIZE );
759
760 /* P2P Action */
761 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
762 (v_U8_t*)P2P_ACTION_FRAME,
763 P2P_ACTION_FRAME_SIZE );
764#endif /* WLAN_FEATURE_P2P */
765}
766
767#ifdef FEATURE_WLAN_WAPI
768void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
769 const u8 *mac_addr, u8 *key , int key_Len)
770{
771 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
772 tCsrRoamSetKey setKey;
773 v_BOOL_t isConnected = TRUE;
774 int status = 0;
775 v_U32_t roamId= 0xFF;
776 tANI_U8 *pKeyPtr = NULL;
777 int n = 0;
778
779 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
780 __func__,pAdapter->device_mode);
781
782 setKey.keyId = key_index; // Store Key ID
783 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
784 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
785 setKey.paeRole = 0 ; // the PAE role
786 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
787 {
788 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
789 }
790 else
791 {
792 isConnected = hdd_connIsConnected(pHddStaCtx);
793 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
794 }
795 setKey.keyLength = key_Len;
796 pKeyPtr = setKey.Key;
797 memcpy( pKeyPtr, key, key_Len);
798
799 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
800 __func__, key_Len);
801 for (n = 0 ; n < key_Len; n++)
802 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
803 __func__,n,setKey.Key[n]);
804
805 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
806 if ( isConnected )
807 {
808 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
809 pAdapter->sessionId, &setKey, &roamId );
810 }
811 if ( status != 0 )
812 {
813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
814 "[%4d] sme_RoamSetKey returned ERROR status= %d",
815 __LINE__, status );
816 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
817 }
818}
819#endif /* FEATURE_WLAN_WAPI*/
820
821#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
822int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
823 beacon_data_t **ppBeacon,
824 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700825#else
826int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
827 beacon_data_t **ppBeacon,
828 struct cfg80211_beacon_data *params,
829 int dtim_period)
830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700831{
832 int size;
833 beacon_data_t *beacon = NULL;
834 beacon_data_t *old = NULL;
835 int head_len,tail_len;
836
Jeff Johnsone7245742012-09-05 17:12:55 -0700837 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700838 if (params->head && !params->head_len)
839 return -EINVAL;
840
841 old = pAdapter->sessionCtx.ap.beacon;
842
843 if (!params->head && !old)
844 return -EINVAL;
845
846 if (params->tail && !params->tail_len)
847 return -EINVAL;
848
849#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
850 /* Kernel 3.0 is not updating dtim_period for set beacon */
851 if (!params->dtim_period)
852 return -EINVAL;
853#endif
854
855 if(params->head)
856 head_len = params->head_len;
857 else
858 head_len = old->head_len;
859
860 if(params->tail || !old)
861 tail_len = params->tail_len;
862 else
863 tail_len = old->tail_len;
864
865 size = sizeof(beacon_data_t) + head_len + tail_len;
866
867 beacon = kzalloc(size, GFP_KERNEL);
868
869 if( beacon == NULL )
870 return -ENOMEM;
871
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700872#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 if(params->dtim_period || !old )
874 beacon->dtim_period = params->dtim_period;
875 else
876 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700877#else
878 if(dtim_period || !old )
879 beacon->dtim_period = dtim_period;
880 else
881 beacon->dtim_period = old->dtim_period;
882#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700883
884 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
885 beacon->tail = beacon->head + head_len;
886 beacon->head_len = head_len;
887 beacon->tail_len = tail_len;
888
889 if(params->head) {
890 memcpy (beacon->head,params->head,beacon->head_len);
891 }
892 else {
893 if(old)
894 memcpy (beacon->head,old->head,beacon->head_len);
895 }
896
897 if(params->tail) {
898 memcpy (beacon->tail,params->tail,beacon->tail_len);
899 }
900 else {
901 if(old)
902 memcpy (beacon->tail,old->tail,beacon->tail_len);
903 }
904
905 *ppBeacon = beacon;
906
907 kfree(old);
908
909 return 0;
910
911}
Jeff Johnson295189b2012-06-20 16:38:30 -0700912
913v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
914{
915 int left = length;
916 v_U8_t *ptr = pIes;
917 v_U8_t elem_id,elem_len;
918
919 while(left >= 2)
920 {
921 elem_id = ptr[0];
922 elem_len = ptr[1];
923 left -= 2;
924 if(elem_len > left)
925 {
926 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700927 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700928 eid,elem_len,left);
929 return NULL;
930 }
931 if (elem_id == eid)
932 {
933 return ptr;
934 }
935
936 left -= elem_len;
937 ptr += (elem_len + 2);
938 }
939 return NULL;
940}
941
Jeff Johnson295189b2012-06-20 16:38:30 -0700942/* Check if rate is 11g rate or not */
943static int wlan_hdd_rate_is_11g(u8 rate)
944{
945 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
946 u8 i;
947 for (i = 0; i < 8; i++)
948 {
949 if(rate == gRateArray[i])
950 return TRUE;
951 }
952 return FALSE;
953}
954
955/* Check for 11g rate and set proper 11g only mode */
956static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
957 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
958{
959 u8 i, num_rates = pIe[0];
960
961 pIe += 1;
962 for ( i = 0; i < num_rates; i++)
963 {
964 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
965 {
966 /* If rate set have 11g rate than change the mode to 11G */
967 *pSapHw_mode = eSAP_DOT11_MODE_11g;
968 if (pIe[i] & BASIC_RATE_MASK)
969 {
970 /* If we have 11g rate as basic rate, it means mode
971 is 11g only mode.
972 */
973 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
974 *pCheckRatesfor11g = FALSE;
975 }
976 }
977 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
978 {
979 *require_ht = TRUE;
980 }
981 }
982 return;
983}
984
985static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
986{
987 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
988 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
989 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
990 u8 checkRatesfor11g = TRUE;
991 u8 require_ht = FALSE;
992 u8 *pIe=NULL;
993
994 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
995
996 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
997 pBeacon->head_len, WLAN_EID_SUPP_RATES);
998 if (pIe != NULL)
999 {
1000 pIe += 1;
1001 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1002 &pConfig->SapHw_mode);
1003 }
1004
1005 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1006 WLAN_EID_EXT_SUPP_RATES);
1007 if (pIe != NULL)
1008 {
1009
1010 pIe += 1;
1011 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1012 &pConfig->SapHw_mode);
1013 }
1014
1015 if( pConfig->channel > 14 )
1016 {
1017 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1018 }
1019
1020 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1021 WLAN_EID_HT_CAPABILITY);
1022
1023 if(pIe)
1024 {
1025 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1026 if(require_ht)
1027 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1028 }
1029}
1030
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001031#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001032static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1033 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001034#else
1035static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1036 struct cfg80211_beacon_data *params)
1037#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001038{
1039 v_U8_t *genie;
1040 v_U8_t total_ielen = 0, ielen = 0;
1041 v_U8_t *pIe = NULL;
1042 v_U8_t addIE[1] = {0};
1043 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -07001044 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001045
1046 genie = vos_mem_malloc(MAX_GENIE_LEN);
1047
1048 if(genie == NULL) {
1049
1050 return -ENOMEM;
1051 }
1052
1053 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1054
1055 if(pIe)
1056 {
1057 /*Copy the wps IE*/
1058 ielen = pIe[1] + 2;
1059 if( ielen <=MAX_GENIE_LEN)
1060 {
1061 vos_mem_copy(genie, pIe, ielen);
1062 }
1063 else
1064 {
1065 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001066 ret = -EINVAL;
1067 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001068 }
1069 total_ielen = ielen;
1070 }
1071
1072#ifdef WLAN_FEATURE_WFD
1073 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1074
1075 if(pIe)
1076 {
1077 ielen = pIe[1] + 2;
1078 if(total_ielen + ielen <= MAX_GENIE_LEN) {
1079 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
1080 }
1081 else {
1082 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001083 ret = -EINVAL;
1084 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001085 }
1086 total_ielen += ielen;
1087 }
1088#endif
1089
1090#ifdef WLAN_FEATURE_P2P
1091 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1092
1093 if(pIe)
1094 {
1095 ielen = pIe[1] + 2;
1096 if(total_ielen + ielen <= MAX_GENIE_LEN)
1097 {
1098 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
1099 }
1100 else
1101 {
1102 hddLog( VOS_TRACE_LEVEL_ERROR,
1103 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001104 ret = -EINVAL;
1105 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 }
1107 total_ielen += ielen;
1108 }
1109#endif
1110
1111 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1112 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1113 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1114 {
1115 hddLog(LOGE,
1116 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001117 ret = -EINVAL;
1118 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 }
1120
1121 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1122 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1123 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1124 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1125 ==eHAL_STATUS_FAILURE)
1126 {
1127 hddLog(LOGE,
1128 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001129 ret = -EINVAL;
1130 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001131 }
1132
1133 // Added for ProResp IE
1134 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1135 {
1136 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1137 u8 probe_rsp_ie_len[3] = {0};
1138 u8 counter = 0;
1139 /* Check Probe Resp Length if it is greater then 255 then Store
1140 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1141 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1142 Store More then 255 bytes into One Variable.
1143 */
1144 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1145 {
1146 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1147 {
1148 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1149 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1150 }
1151 else
1152 {
1153 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1154 rem_probe_resp_ie_len = 0;
1155 }
1156 }
1157
1158 rem_probe_resp_ie_len = 0;
1159
1160 if (probe_rsp_ie_len[0] > 0)
1161 {
1162 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1163 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1164 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1165 probe_rsp_ie_len[0], NULL,
1166 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1167 {
1168 hddLog(LOGE,
1169 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001170 ret = -EINVAL;
1171 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 }
1173 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1174 }
1175
1176 if (probe_rsp_ie_len[1] > 0)
1177 {
1178 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1179 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1180 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1181 probe_rsp_ie_len[1], NULL,
1182 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1183 {
1184 hddLog(LOGE,
1185 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001186 ret = -EINVAL;
1187 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001188 }
1189 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1190 }
1191
1192 if (probe_rsp_ie_len[2] > 0)
1193 {
1194 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1195 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1196 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1197 probe_rsp_ie_len[2], NULL,
1198 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1199 {
1200 hddLog(LOGE,
1201 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001202 ret = -EINVAL;
1203 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 }
1205 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1206 }
1207
1208 if (probe_rsp_ie_len[1] == 0 )
1209 {
1210 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1211 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1212 eANI_BOOLEAN_FALSE) )
1213 {
1214 hddLog(LOGE,
1215 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1216 }
1217 }
1218
1219 if (probe_rsp_ie_len[2] == 0 )
1220 {
1221 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1222 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1223 eANI_BOOLEAN_FALSE) )
1224 {
1225 hddLog(LOGE,
1226 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1227 }
1228 }
1229
1230 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1231 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1232 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1233 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1234 == eHAL_STATUS_FAILURE)
1235 {
1236 hddLog(LOGE,
1237 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001238 ret = -EINVAL;
1239 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 }
1241 }
1242 else
1243 {
1244 // Reset WNI_CFG_PROBE_RSP Flags
1245 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1246
1247 hddLog(VOS_TRACE_LEVEL_INFO,
1248 "%s: No Probe Response IE received in set beacon",
1249 __func__);
1250 }
1251
1252 // Added for AssocResp IE
1253 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1254 {
1255 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1256 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1257 params->assocresp_ies_len, NULL,
1258 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1259 {
1260 hddLog(LOGE,
1261 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001262 ret = -EINVAL;
1263 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001264 }
1265
1266 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1267 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1268 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1269 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1270 == eHAL_STATUS_FAILURE)
1271 {
1272 hddLog(LOGE,
1273 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001274 ret = -EINVAL;
1275 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 }
1277 }
1278 else
1279 {
1280 hddLog(VOS_TRACE_LEVEL_INFO,
1281 "%s: No Assoc Response IE received in set beacon",
1282 __func__);
1283
1284 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1285 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1286 eANI_BOOLEAN_FALSE) )
1287 {
1288 hddLog(LOGE,
1289 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1290 }
1291 }
1292
Jeff Johnsone7245742012-09-05 17:12:55 -07001293done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 vos_mem_free(genie);
1295 return 0;
1296}
Jeff Johnson295189b2012-06-20 16:38:30 -07001297
1298/*
1299 * FUNCTION: wlan_hdd_validate_operation_channel
1300 * called by wlan_hdd_cfg80211_start_bss() and
1301 * wlan_hdd_cfg80211_set_channel()
1302 * This function validates whether given channel is part of valid
1303 * channel list.
1304 */
1305static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1306{
1307
1308 v_U32_t num_ch = 0;
1309 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1310 u32 indx = 0;
1311 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1312
1313 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1314
1315 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1316 valid_ch, &num_ch))
1317 {
1318 hddLog(VOS_TRACE_LEVEL_ERROR,
1319 "%s: failed to get valid channel list\n", __func__);
1320 return VOS_STATUS_E_FAILURE;
1321 }
1322
1323 for (indx = 0; indx < num_ch; indx++)
1324 {
1325 if (channel == valid_ch[indx])
1326 {
1327 break;
1328 }
1329 }
1330
1331 if (indx >= num_ch)
1332 {
1333 hddLog(VOS_TRACE_LEVEL_ERROR,
1334 "%s: Invalid Channel [%d] \n", __func__, channel);
1335 return VOS_STATUS_E_FAILURE;
1336 }
1337 return VOS_STATUS_SUCCESS;
1338
1339}
1340
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301341/*
1342 * FUNCTION: wlan_hdd_select_cbmode
1343 * called by wlan_hdd_cfg80211_start_bss() and
1344 * This function selects the cbmode based on primary channel
1345 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001346VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301347{
1348 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001349 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1350 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1351
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301352 if(
1353#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001354 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1355 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301356#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001357 SapHw_mode != eSAP_DOT11_MODE_11n &&
1358 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301359 )
1360 {
1361 return VOS_STATUS_SUCCESS;
1362 }
1363
1364 if (!pConfigIni->nChannelBondingMode5GHz) {
1365 return VOS_STATUS_SUCCESS;
1366 }
1367
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001368 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301369 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1370
1371 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1372
1373#ifdef WLAN_FEATURE_11AC
1374
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001375 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1376 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301377 {
1378 if ( channel== 36 || channel == 52 || channel == 100 ||
1379 channel == 116 || channel == 149 )
1380 {
1381 smeConfig.csrConfig.channelBondingMode5GHz =
1382 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1383 }
1384 else if ( channel == 40 || channel == 56 || channel == 104 ||
1385 channel == 120 || channel == 153 )
1386 {
1387 smeConfig.csrConfig.channelBondingMode5GHz =
1388 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1389 }
1390 else if ( channel == 44 || channel == 60 || channel == 108 ||
1391 channel == 124 || channel == 157 )
1392 {
1393 smeConfig.csrConfig.channelBondingMode5GHz =
1394 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1395 }
1396 else if ( channel == 48 || channel == 64 || channel == 112 ||
1397 channel == 128 || channel == 161 )
1398 {
1399 smeConfig.csrConfig.channelBondingMode5GHz =
1400 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1401 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301402 }
1403#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001404 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1405 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301406 {
1407 if ( channel== 40 || channel == 48 || channel == 56 ||
1408 channel == 64 || channel == 104 || channel == 112 ||
1409 channel == 120 || channel == 128 || channel == 136 ||
1410 channel == 144 || channel == 153 || channel == 161 )
1411 {
1412 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1413 }
1414 else if ( channel== 36 || channel == 44 || channel == 52 ||
1415 channel == 60 || channel == 100 || channel == 108 ||
1416 channel == 116 || channel == 124 || channel == 132 ||
1417 channel == 140 || channel == 149 || channel == 157 )
1418 {
1419 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1420 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301421 }
1422 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1423
1424 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1425 return VOS_STATUS_SUCCESS;
1426}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001427
Jeff Johnson295189b2012-06-20 16:38:30 -07001428#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1429static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1430 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001431#else
1432static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1433 struct cfg80211_beacon_data *params,
1434 const u8 *ssid, size_t ssid_len,
1435 enum nl80211_hidden_ssid hidden_ssid)
1436#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001437{
1438 tsap_Config_t *pConfig;
1439 beacon_data_t *pBeacon = NULL;
1440 struct ieee80211_mgmt *pMgmt_frame;
1441 v_U8_t *pIe=NULL;
1442 v_U16_t capab_info;
1443 eCsrAuthType RSNAuthType;
1444 eCsrEncryptionType RSNEncryptType;
1445 eCsrEncryptionType mcRSNEncryptType;
1446 int status = VOS_STATUS_SUCCESS;
1447 tpWLAN_SAPEventCB pSapEventCallback;
1448 hdd_hostapd_state_t *pHostapdState;
1449 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1450 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301451 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 struct qc_mac_acl_entry *acl_entry = NULL;
1453 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001454 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001455
1456 ENTER();
1457
1458 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1459
1460 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1461
1462 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1463
1464 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1465
1466 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1467
1468 //channel is already set in the set_channel Call back
1469 //pConfig->channel = pCommitConfig->channel;
1470
1471 /*Protection parameter to enable or disable*/
1472 pConfig->protEnabled =
1473 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1474
1475 pConfig->dtim_period = pBeacon->dtim_period;
1476
1477 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1478 pConfig->dtim_period);
1479
1480
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001481 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001482 {
1483 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001485 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001487 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001488 pConfig->ieee80211d = 1;
1489 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1490 sme_setRegInfo(hHal, pConfig->countryCode);
1491 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001493 else
1494 {
1495 pConfig->ieee80211d = 0;
1496 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301497 /*
1498 * If auto channel is configured i.e. channel is 0,
1499 * so skip channel validation.
1500 */
1501 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1502 {
1503 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1504 {
1505 hddLog(VOS_TRACE_LEVEL_ERROR,
1506 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1507 return -EINVAL;
1508 }
1509 }
1510 else
1511 {
1512 if(1 != pHddCtx->is_dynamic_channel_range_set)
1513 {
1514 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1515 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1516 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1517 }
1518 pHddCtx->is_dynamic_channel_range_set = 0;
1519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001520 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001521 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001522 {
1523 pConfig->ieee80211d = 0;
1524 }
1525 pConfig->authType = eSAP_AUTO_SWITCH;
1526
1527 capab_info = pMgmt_frame->u.beacon.capab_info;
1528
1529 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1530 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1531
1532 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1533
1534 /*Set wps station to configured*/
1535 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1536
1537 if(pIe)
1538 {
1539 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1540 {
1541 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1542 return -EINVAL;
1543 }
1544 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1545 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001546 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001547 /* Check 15 bit of WPS IE as it contain information for wps state
1548 * WPS state
1549 */
1550 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1551 {
1552 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1553 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1554 {
1555 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1556 }
1557 }
1558 }
1559 else
1560 {
1561 pConfig->wps_state = SAP_WPS_DISABLED;
1562 }
1563 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1564
1565 pConfig->RSNWPAReqIELength = 0;
1566 pConfig->pRSNWPAReqIE = NULL;
1567 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1568 WLAN_EID_RSN);
1569 if(pIe && pIe[1])
1570 {
1571 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1572 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1573 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1574 /* The actual processing may eventually be more extensive than
1575 * this. Right now, just consume any PMKIDs that are sent in
1576 * by the app.
1577 * */
1578 status = hdd_softap_unpackIE(
1579 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1580 &RSNEncryptType,
1581 &mcRSNEncryptType,
1582 &RSNAuthType,
1583 pConfig->pRSNWPAReqIE[1]+2,
1584 pConfig->pRSNWPAReqIE );
1585
1586 if( VOS_STATUS_SUCCESS == status )
1587 {
1588 /* Now copy over all the security attributes you have
1589 * parsed out
1590 * */
1591 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1592 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1593 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1594 = RSNEncryptType;
1595 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1596 "EncryptionType = %d mcEncryptionType = %d\n"),
1597 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1598 }
1599 }
1600
1601 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1602 pBeacon->tail, pBeacon->tail_len);
1603
1604 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1605 {
1606 if (pConfig->pRSNWPAReqIE)
1607 {
1608 /*Mixed mode WPA/WPA2*/
1609 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1610 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1611 }
1612 else
1613 {
1614 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1615 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1616 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1617 status = hdd_softap_unpackIE(
1618 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1619 &RSNEncryptType,
1620 &mcRSNEncryptType,
1621 &RSNAuthType,
1622 pConfig->pRSNWPAReqIE[1]+2,
1623 pConfig->pRSNWPAReqIE );
1624
1625 if( VOS_STATUS_SUCCESS == status )
1626 {
1627 /* Now copy over all the security attributes you have
1628 * parsed out
1629 * */
1630 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1631 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1632 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1633 = RSNEncryptType;
1634 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1635 "EncryptionType = %d mcEncryptionType = %d\n"),
1636 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1637 }
1638 }
1639 }
1640
1641 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1642
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001643#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 if (params->ssid != NULL)
1645 {
1646 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1647 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1648 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1649 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1650 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001651#else
1652 if (ssid != NULL)
1653 {
1654 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1655 pConfig->SSIDinfo.ssid.length = ssid_len;
1656 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1657 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1658 }
1659#endif
1660
Jeff Johnson295189b2012-06-20 16:38:30 -07001661 vos_mem_copy(pConfig->self_macaddr.bytes,
1662 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1663
1664 /* default value */
1665 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1666 pConfig->num_accept_mac = 0;
1667 pConfig->num_deny_mac = 0;
1668
1669 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1670 pBeacon->tail, pBeacon->tail_len);
1671
1672 /* pIe for black list is following form:
1673 type : 1 byte
1674 length : 1 byte
1675 OUI : 4 bytes
1676 acl type : 1 byte
1677 no of mac addr in black list: 1 byte
1678 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1679 */
1680 if ((pIe != NULL) && (pIe[1] != 0))
1681 {
1682 pConfig->SapMacaddr_acl = pIe[6];
1683 pConfig->num_deny_mac = pIe[7];
1684 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1685 pIe[6], pIe[7]);
1686 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1687 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1688 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1689 for (i = 0; i < pConfig->num_deny_mac; i++)
1690 {
1691 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1692 acl_entry++;
1693 }
1694 }
1695 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1696 pBeacon->tail, pBeacon->tail_len);
1697
1698 /* pIe for white list is following form:
1699 type : 1 byte
1700 length : 1 byte
1701 OUI : 4 bytes
1702 acl type : 1 byte
1703 no of mac addr in white list: 1 byte
1704 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1705 */
1706 if ((pIe != NULL) && (pIe[1] != 0))
1707 {
1708 pConfig->SapMacaddr_acl = pIe[6];
1709 pConfig->num_accept_mac = pIe[7];
1710 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1711 pIe[6], pIe[7]);
1712 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1713 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1714 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1715 for (i = 0; i < pConfig->num_accept_mac; i++)
1716 {
1717 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1718 acl_entry++;
1719 }
1720 }
1721 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1722
Jeff Johnsone7245742012-09-05 17:12:55 -07001723#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001724 /* Overwrite the hostapd setting for HW mode only for 11ac.
1725 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1726 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1727 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1728 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1729 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1730 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1731 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001732 {
1733 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1734 }
1735#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301736
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001737 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1738 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 // ht_capab is not what the name conveys,this is used for protection bitmap
1740 pConfig->ht_capab =
1741 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1742
1743 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1744 {
1745 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1746 return -EINVAL;
1747 }
1748
1749 //Uapsd Enabled Bit
1750 pConfig->UapsdEnable =
1751 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1752 //Enable OBSS protection
1753 pConfig->obssProtEnabled =
1754 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1755
1756 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1757 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1758 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1759 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1760 (int)pConfig->channel);
1761 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1762 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1763 pConfig->authType);
1764 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1765 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1766 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1767 pConfig->protEnabled, pConfig->obssProtEnabled);
1768
1769 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1770 {
1771 //Bss already started. just return.
1772 //TODO Probably it should update some beacon params.
1773 hddLog( LOGE, "Bss Already started...Ignore the request");
1774 EXIT();
1775 return 0;
1776 }
1777
1778 pConfig->persona = pHostapdAdapter->device_mode;
1779
1780 pSapEventCallback = hdd_hostapd_SAPEventCB;
1781 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1782 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1783 {
1784 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1785 return -EINVAL;
1786 }
1787
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001788 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1790
1791 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1792
1793 if (!VOS_IS_STATUS_SUCCESS(status))
1794 {
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 ("ERROR: HDD vos wait for single_event failed!!\n"));
1797 VOS_ASSERT(0);
1798 }
1799
1800 //Succesfully started Bss update the state bit.
1801 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1802
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001803#ifdef WLAN_FEATURE_P2P_DEBUG
1804 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1805 {
1806 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1807 {
1808 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1809 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001810 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001811 }
1812 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1813 {
1814 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1815 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001816 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001817 }
1818 }
1819#endif
1820
Jeff Johnson295189b2012-06-20 16:38:30 -07001821 pHostapdState->bCommit = TRUE;
1822 EXIT();
1823
1824 return 0;
1825}
1826
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001827#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001828static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1829 struct net_device *dev,
1830 struct beacon_parameters *params)
1831{
1832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1833 int status=VOS_STATUS_SUCCESS;
1834
1835 ENTER();
1836
1837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1838
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001839 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1840 {
1841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1842 "%s:LOGP in Progress. Ignore!!!", __func__);
1843 return -EAGAIN;
1844 }
1845
Jeff Johnson295189b2012-06-20 16:38:30 -07001846 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1847#ifdef WLAN_FEATURE_P2P
1848 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1849#endif
1850 )
1851 {
1852 beacon_data_t *old,*new;
1853
1854 old = pAdapter->sessionCtx.ap.beacon;
1855
1856 if (old)
1857 return -EALREADY;
1858
1859 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1860
1861 if(status != VOS_STATUS_SUCCESS)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,
1864 "%s:Error!!! Allocating the new beacon\n",__func__);
1865 return -EINVAL;
1866 }
1867
1868 pAdapter->sessionCtx.ap.beacon = new;
1869
1870 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1871 }
1872
1873 EXIT();
1874 return status;
1875}
1876
1877static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
1878 struct net_device *dev,
1879 struct beacon_parameters *params)
1880{
1881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1882 int status=VOS_STATUS_SUCCESS;
1883
1884 ENTER();
1885
1886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1887 __func__,pAdapter->device_mode);
1888
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001889 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1890 {
1891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1892 "%s:LOGP in Progress. Ignore!!!", __func__);
1893 return -EAGAIN;
1894 }
1895
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1897#ifdef WLAN_FEATURE_P2P
1898 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1899#endif
1900 )
1901 {
1902 beacon_data_t *old,*new;
1903
1904 old = pAdapter->sessionCtx.ap.beacon;
1905
1906 if (!old)
1907 return -ENOENT;
1908
1909 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1910
1911 if(status != VOS_STATUS_SUCCESS) {
1912 hddLog(VOS_TRACE_LEVEL_FATAL,
1913 "%s: Error!!! Allocating the new beacon\n",__func__);
1914 return -EINVAL;
1915 }
1916
1917 pAdapter->sessionCtx.ap.beacon = new;
1918
1919 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1920 }
1921
1922 EXIT();
1923 return status;
1924}
1925
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001926#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1927
1928#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001929static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
1930 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001931#else
1932static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
1933 struct net_device *dev)
1934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001935{
1936 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001937 hdd_context_t *pHddCtx = NULL;
1938 hdd_scaninfo_t *pScanInfo = NULL;
1939 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 VOS_STATUS status = 0;
1941
1942 ENTER();
1943
1944 if (NULL == pAdapter)
1945 {
1946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001947 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001948 return -ENODEV;
1949 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001950 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1951 {
1952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1953 "%s:LOGP in Progress. Ignore!!!", __func__);
1954 return -EAGAIN;
1955 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001956
1957 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1958 if (NULL == pHddCtx)
1959 {
1960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001961 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001962 return -ENODEV;
1963 }
1964
1965 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
1966 if (NULL == staAdapter)
1967 {
1968 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
1969 if (NULL == staAdapter)
1970 {
1971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001972 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001973 return -ENODEV;
1974 }
1975 }
1976
1977 pScanInfo = &pHddCtx->scan_info;
1978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1980 {
1981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1982 return -EAGAIN;
1983 }
1984
1985 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1986
1987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1988 __func__,pAdapter->device_mode);
1989
Jeff Johnsone7245742012-09-05 17:12:55 -07001990 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
1991 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001992 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07001993 hdd_abort_mac_scan(staAdapter->pHddCtx);
1994 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08001995 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07001996 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
1997 if (!status)
1998 {
1999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002000 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002001 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002002 VOS_ASSERT(pScanInfo->mScanPending);
2003 return 0;
2004 }
2005 }
2006
Jeff Johnson295189b2012-06-20 16:38:30 -07002007 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2008#ifdef WLAN_FEATURE_P2P
2009 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2010#endif
2011 )
2012 {
2013 beacon_data_t *old;
2014
2015 old = pAdapter->sessionCtx.ap.beacon;
2016
2017 if (!old)
2018 return -ENOENT;
2019
2020#ifdef CONFIG_CFG80211
2021 hdd_cleanup_actionframe(pHddCtx, pAdapter);
2022#endif
2023
2024 mutex_lock(&pHddCtx->sap_lock);
2025 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2026 {
2027 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2028 {
2029 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2030
2031 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2032
2033 if (!VOS_IS_STATUS_SUCCESS(status))
2034 {
2035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2036 ("ERROR: HDD vos wait for single_event failed!!\n"));
2037 VOS_ASSERT(0);
2038 }
2039 }
2040 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2041 }
2042 mutex_unlock(&pHddCtx->sap_lock);
2043
2044 if(status != VOS_STATUS_SUCCESS)
2045 {
2046 hddLog(VOS_TRACE_LEVEL_FATAL,
2047 "%s:Error!!! Stopping the BSS\n",__func__);
2048 return -EINVAL;
2049 }
2050
2051 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2052 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2053 ==eHAL_STATUS_FAILURE)
2054 {
2055 hddLog(LOGE,
2056 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2057 }
2058
2059 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2060 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2061 eANI_BOOLEAN_FALSE) )
2062 {
2063 hddLog(LOGE,
2064 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2065 }
2066
2067 // Reset WNI_CFG_PROBE_RSP Flags
2068 wlan_hdd_reset_prob_rspies(pAdapter);
2069
2070 pAdapter->sessionCtx.ap.beacon = NULL;
2071 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002072#ifdef WLAN_FEATURE_P2P_DEBUG
2073 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2074 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2075 {
2076 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2077 "GO got removed");
2078 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2079 }
2080#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 }
2082 EXIT();
2083 return status;
2084}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002085
2086#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2087
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302088static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2089 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002090 struct cfg80211_ap_settings *params)
2091{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302092 hdd_adapter_t *pAdapter;
2093 hdd_context_t *pHddCtx;
2094 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002095
2096 ENTER();
2097
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302098 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002099 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2101 "%s: Device is Null", __func__);
2102 return -ENODEV;
2103 }
2104
2105 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2106 if (NULL == pAdapter)
2107 {
2108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2109 "%s: HDD adapter is Null", __func__);
2110 return -ENODEV;
2111 }
2112
2113 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2116 "%s: HDD adapter magic is invalid", __func__);
2117 return -ENODEV;
2118 }
2119
2120 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2121 if (NULL == pHddCtx)
2122 {
2123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2124 "%s: HDD context is Null", __func__);
2125 return -ENODEV;
2126 }
2127
2128 if (pHddCtx->isLogpInProgress)
2129 {
2130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2131 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002132 return -EAGAIN;
2133 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302134
2135 if (pHddCtx->isLoadUnloadInProgress)
2136 {
2137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2138 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2139 return -EAGAIN;
2140 }
2141
2142 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2143 __func__, pAdapter->device_mode);
2144
2145 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002146#ifdef WLAN_FEATURE_P2P
2147 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2148#endif
2149 )
2150 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302151 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002152
2153 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302154
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002155 if (old)
2156 return -EALREADY;
2157
2158 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2159
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302160 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002161 {
2162 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302163 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002164 return -EINVAL;
2165 }
2166 pAdapter->sessionCtx.ap.beacon = new;
2167 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2168 params->ssid_len, params->hidden_ssid);
2169 }
2170
2171 EXIT();
2172 return status;
2173}
2174
2175
2176static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2177 struct net_device *dev,
2178 struct cfg80211_beacon_data *params)
2179{
2180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2181 int status=VOS_STATUS_SUCCESS;
2182
2183 ENTER();
2184
2185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2186 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002187 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2188 {
2189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2190 return -EAGAIN;
2191 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002192
2193 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2194#ifdef WLAN_FEATURE_P2P
2195 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2196#endif
2197 )
2198 {
2199 beacon_data_t *old,*new;
2200
2201 old = pAdapter->sessionCtx.ap.beacon;
2202
2203 if (!old)
2204 return -ENOENT;
2205
2206 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2207
2208 if(status != VOS_STATUS_SUCCESS) {
2209 hddLog(VOS_TRACE_LEVEL_FATAL,
2210 "%s: Error!!! Allocating the new beacon\n",__func__);
2211 return -EINVAL;
2212 }
2213
2214 pAdapter->sessionCtx.ap.beacon = new;
2215
2216 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2217 }
2218
2219 EXIT();
2220 return status;
2221}
2222
2223#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2224
Jeff Johnson295189b2012-06-20 16:38:30 -07002225
2226static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2227 struct net_device *dev,
2228 struct bss_parameters *params)
2229{
2230 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2231
2232 ENTER();
2233
2234 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2235 __func__,pAdapter->device_mode);
2236
2237 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2238#ifdef WLAN_FEATURE_P2P
2239 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2240#endif
2241 )
2242 {
2243 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2244 * want to update this parameter */
2245 if (-1 != params->ap_isolate)
2246 {
2247 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2248 }
2249 }
2250
2251 EXIT();
2252 return 0;
2253}
2254
2255/*
2256 * FUNCTION: wlan_hdd_cfg80211_change_iface
2257 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2258 */
2259int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2260 struct net_device *ndev,
2261 enum nl80211_iftype type,
2262 u32 *flags,
2263 struct vif_params *params
2264 )
2265{
2266 struct wireless_dev *wdev;
2267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2268 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002269 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 tCsrRoamProfile *pRoamProfile = NULL;
2271 eCsrRoamBssType LastBSSType;
2272 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2273 eMib_dot11DesiredBssType connectedBssType;
2274 VOS_STATUS status;
2275
2276 ENTER();
2277
2278 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2279 {
2280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2281 return -EAGAIN;
2282 }
2283
2284 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2285 __func__, pAdapter->device_mode);
2286
2287 wdev = ndev->ieee80211_ptr;
2288
2289#ifdef WLAN_BTAMP_FEATURE
2290 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2291 (NL80211_IFTYPE_ADHOC == type)||
2292 (NL80211_IFTYPE_AP == type)||
2293 (NL80211_IFTYPE_P2P_GO == type))
2294 {
2295 pHddCtx->isAmpAllowed = VOS_FALSE;
2296 // stop AMP traffic
2297 status = WLANBAP_StopAmp();
2298 if(VOS_STATUS_SUCCESS != status )
2299 {
2300 pHddCtx->isAmpAllowed = VOS_TRUE;
2301 hddLog(VOS_TRACE_LEVEL_FATAL,
2302 "%s: Failed to stop AMP", __func__);
2303 return -EINVAL;
2304 }
2305 }
2306#endif //WLAN_BTAMP_FEATURE
2307 /* Reset the current device mode bit mask*/
2308 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2309
2310 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2311#ifdef WLAN_FEATURE_P2P
2312 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002313 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002314#endif
2315 )
2316 {
2317 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2318 pRoamProfile = &pWextState->roamProfile;
2319 LastBSSType = pRoamProfile->BSSType;
2320
2321 switch (type)
2322 {
2323 case NL80211_IFTYPE_STATION:
2324#ifdef WLAN_FEATURE_P2P
2325 case NL80211_IFTYPE_P2P_CLIENT:
2326#endif
2327 hddLog(VOS_TRACE_LEVEL_INFO,
2328 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2329 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002330#ifdef WLAN_FEATURE_11AC
2331 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2332 {
2333 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2334 }
2335#endif
2336 pRoamProfile->phyMode =
2337 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 wdev->iftype = type;
2339#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002340 //Check for sub-string p2p to confirm its a p2p interface
2341 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002342 {
2343 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2344 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2345 }
2346 else
2347 {
2348 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002349 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002351#endif
2352 break;
2353 case NL80211_IFTYPE_ADHOC:
2354 hddLog(VOS_TRACE_LEVEL_INFO,
2355 "%s: setting interface Type to ADHOC", __func__);
2356 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2357 pRoamProfile->phyMode =
2358 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2359 wdev->iftype = type;
2360 break;
2361
2362 case NL80211_IFTYPE_AP:
2363#ifdef WLAN_FEATURE_P2P
2364 case NL80211_IFTYPE_P2P_GO:
2365#endif
2366 {
2367 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2368 "%s: setting interface Type to %s", __func__,
2369 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2370
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002371 //Cancel any remain on channel for GO mode
2372 if (NL80211_IFTYPE_P2P_GO == type)
2373 {
2374 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2375 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002376 if (NL80211_IFTYPE_AP == type)
2377 {
2378 /* As Loading WLAN Driver one interface being created for p2p device
2379 * address. This will take one HW STA and the max number of clients
2380 * that can connect to softAP will be reduced by one. so while changing
2381 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2382 * interface as it is not required in SoftAP mode.
2383 */
2384
2385 // Get P2P Adapter
2386 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2387
2388 if (pP2pAdapter)
2389 {
2390 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2391 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2392 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2393 }
2394 }
2395
Jeff Johnson295189b2012-06-20 16:38:30 -07002396 //De-init the adapter.
2397 hdd_stop_adapter( pHddCtx, pAdapter );
2398 hdd_deinit_adapter( pHddCtx, pAdapter );
2399 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2400#ifdef WLAN_SOFTAP_FEATURE
2401#ifdef WLAN_FEATURE_P2P
2402 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2403 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2404#else
2405 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2406#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002407
2408 //Disable BMPS and IMPS if enabled
2409 //before starting Go
2410 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2411 {
2412 if(VOS_STATUS_E_FAILURE ==
2413 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2414 {
2415 //Fail to Exit BMPS
2416 VOS_ASSERT(0);
2417 }
2418 }
2419
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002420 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2421 (pConfig->apRandomBssidEnabled))
2422 {
2423 /* To meet Android requirements create a randomized
2424 MAC address of the form 02:1A:11:Fx:xx:xx */
2425 get_random_bytes(&ndev->dev_addr[3], 3);
2426 ndev->dev_addr[0] = 0x02;
2427 ndev->dev_addr[1] = 0x1A;
2428 ndev->dev_addr[2] = 0x11;
2429 ndev->dev_addr[3] |= 0xF0;
2430 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2431 VOS_MAC_ADDR_SIZE);
2432 pr_info("wlan: Generated HotSpot BSSID "
2433 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2434 ndev->dev_addr[0],
2435 ndev->dev_addr[1],
2436 ndev->dev_addr[2],
2437 ndev->dev_addr[3],
2438 ndev->dev_addr[4],
2439 ndev->dev_addr[5]);
2440 }
2441
Jeff Johnson295189b2012-06-20 16:38:30 -07002442 hdd_set_ap_ops( pAdapter->dev );
2443
2444 status = hdd_init_ap_mode(pAdapter);
2445 if(status != VOS_STATUS_SUCCESS)
2446 {
2447 hddLog(VOS_TRACE_LEVEL_FATAL,
2448 "%s: Error initializing the ap mode", __func__);
2449 return -EINVAL;
2450 }
2451 hdd_set_conparam(1);
2452
2453#endif
2454 /*interface type changed update in wiphy structure*/
2455 if(wdev)
2456 {
2457 wdev->iftype = type;
2458 pHddCtx->change_iface = type;
2459 }
2460 else
2461 {
2462 hddLog(VOS_TRACE_LEVEL_ERROR,
2463 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2464 return -EINVAL;
2465 }
2466 goto done;
2467 }
2468
2469 default:
2470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2471 __func__);
2472 return -EOPNOTSUPP;
2473 }
2474 }
2475 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2476#ifdef WLAN_FEATURE_P2P
2477 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2478#endif
2479 )
2480 {
2481 switch(type)
2482 {
2483 case NL80211_IFTYPE_STATION:
2484#ifdef WLAN_FEATURE_P2P
2485 case NL80211_IFTYPE_P2P_CLIENT:
2486#endif
2487 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002488 hdd_stop_adapter( pHddCtx, pAdapter );
2489 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002490 wdev->iftype = type;
2491#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002492 //Check for sub-string p2p to confirm its a p2p interface
2493 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002494 {
2495 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2496 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2497 }
2498 else
2499 {
2500 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002501 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002503#endif
2504 hdd_set_conparam(0);
2505 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2507 hdd_set_station_ops( pAdapter->dev );
2508 status = hdd_init_station_mode( pAdapter );
2509 if( VOS_STATUS_SUCCESS != status )
2510 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002511 /* In case of JB, for P2P-GO, only change interface will be called,
2512 * This is the right place to enable back bmps_imps()
2513 */
2514 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002515 goto done;
2516 case NL80211_IFTYPE_AP:
2517#ifdef WLAN_FEATURE_P2P
2518 case NL80211_IFTYPE_P2P_GO:
2519#endif
2520 wdev->iftype = type;
2521#ifdef WLAN_FEATURE_P2P
2522 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2523 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2524#endif
2525 goto done;
2526 default:
2527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2528 __func__);
2529 return -EOPNOTSUPP;
2530
2531 }
2532
2533 }
2534 else
2535 {
2536 return -EOPNOTSUPP;
2537 }
2538
2539
2540 if(pRoamProfile)
2541 {
2542 if ( LastBSSType != pRoamProfile->BSSType )
2543 {
2544 /*interface type changed update in wiphy structure*/
2545 wdev->iftype = type;
2546
2547 /*the BSS mode changed, We need to issue disconnect
2548 if connected or in IBSS disconnect state*/
2549 if ( hdd_connGetConnectedBssType(
2550 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2551 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2552 {
2553 /*need to issue a disconnect to CSR.*/
2554 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2555 if( eHAL_STATUS_SUCCESS ==
2556 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2557 pAdapter->sessionId,
2558 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2559 {
2560 wait_for_completion_interruptible_timeout(
2561 &pAdapter->disconnect_comp_var,
2562 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2563 }
2564 }
2565 }
2566 }
2567
2568done:
2569 /*set bitmask based on updated value*/
2570 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2571#ifdef WLAN_BTAMP_FEATURE
2572 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2573 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2574 {
2575 //we are ok to do AMP
2576 pHddCtx->isAmpAllowed = VOS_TRUE;
2577 }
2578#endif //WLAN_BTAMP_FEATURE
2579 EXIT();
2580 return 0;
2581}
2582
2583static int wlan_hdd_change_station(struct wiphy *wiphy,
2584 struct net_device *dev,
2585 u8 *mac,
2586 struct station_parameters *params)
2587{
2588 VOS_STATUS status = VOS_STATUS_SUCCESS;
2589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2590 v_MACADDR_t STAMacAddress;
2591
Jeff Johnsone7245742012-09-05 17:12:55 -07002592 ENTER();
2593
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002594 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2595 {
2596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2597 "%s:LOGP in Progress. Ignore!!!", __func__);
2598 return -EAGAIN;
2599 }
2600
Jeff Johnson295189b2012-06-20 16:38:30 -07002601 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2602
2603 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2604#ifdef WLAN_FEATURE_P2P
2605 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2606#endif
2607 )
2608 {
2609 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2610 {
2611 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2612 WLANTL_STA_AUTHENTICATED);
2613
2614 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002615 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002616 return -EINVAL;
2617 }
2618 }
2619
Jeff Johnsone7245742012-09-05 17:12:55 -07002620 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002621 return status;
2622}
2623
2624/*
2625 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2626 * This function is used to get peer station index in IBSS mode
2627 */
2628static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2629{
2630 u8 idx = 0;
2631 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2632 ENTER();
2633 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2634 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2635 {
2636 if ( (0 !=
2637 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2638 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2639 temp, VOS_MAC_ADDR_SIZE)
2640 )
2641 {
2642 return idx;
2643 }
2644 }
2645 return idx;
2646}
2647
2648
2649/*
2650 * FUNCTION: wlan_hdd_cfg80211_add_key
2651 * This function is used to initialize the key information
2652 */
2653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2654static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2655 struct net_device *ndev,
2656 u8 key_index, bool pairwise,
2657 const u8 *mac_addr,
2658 struct key_params *params
2659 )
2660#else
2661static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2662 struct net_device *ndev,
2663 u8 key_index, const u8 *mac_addr,
2664 struct key_params *params
2665 )
2666#endif
2667{
2668 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2669 tCsrRoamSetKey setKey;
2670 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2671 int status = 0;
2672 v_U32_t roamId= 0xFF;
2673 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2674 hdd_hostapd_state_t *pHostapdState;
2675 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002676 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002677
2678 ENTER();
2679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002680 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2681 {
2682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2683 "%s:LOGP in Progress. Ignore!!!", __func__);
2684 return -EAGAIN;
2685 }
2686
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2688 __func__,pAdapter->device_mode);
2689
2690 if (CSR_MAX_NUM_KEY <= key_index)
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2693 key_index);
2694
2695 return -EINVAL;
2696 }
2697
2698 hddLog(VOS_TRACE_LEVEL_INFO,
2699 "%s: called with key index = %d & key length %d",
2700 __func__, key_index, params->key_len);
2701
2702 /*extract key idx, key len and key*/
2703 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2704 setKey.keyId = key_index;
2705 setKey.keyLength = params->key_len;
2706 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2707
2708 switch (params->cipher)
2709 {
2710 case WLAN_CIPHER_SUITE_WEP40:
2711 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2712 break;
2713
2714 case WLAN_CIPHER_SUITE_WEP104:
2715 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2716 break;
2717
2718 case WLAN_CIPHER_SUITE_TKIP:
2719 {
2720 u8 *pKey = &setKey.Key[0];
2721 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2722
2723 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2724
2725 /*Supplicant sends the 32bytes key in this order
2726
2727 |--------------|----------|----------|
2728 | Tk1 |TX-MIC | RX Mic |
2729 |--------------|----------|----------|
2730 <---16bytes---><--8bytes--><--8bytes-->
2731
2732 */
2733 /*Sme expects the 32 bytes key to be in the below order
2734
2735 |--------------|----------|----------|
2736 | Tk1 |RX-MIC | TX Mic |
2737 |--------------|----------|----------|
2738 <---16bytes---><--8bytes--><--8bytes-->
2739 */
2740 /* Copy the Temporal Key 1 (TK1) */
2741 vos_mem_copy(pKey, params->key,16);
2742
2743 /*Copy the rx mic first*/
2744 vos_mem_copy(&pKey[16],&params->key[24],8);
2745
2746 /*Copy the tx mic */
2747 vos_mem_copy(&pKey[24],&params->key[16],8);
2748
2749
2750 break;
2751 }
2752
2753 case WLAN_CIPHER_SUITE_CCMP:
2754 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2755 break;
2756
2757#ifdef FEATURE_WLAN_WAPI
2758 case WLAN_CIPHER_SUITE_SMS4:
2759 {
2760 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2761 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2762 params->key, params->key_len);
2763 return 0;
2764 }
2765#endif
2766#ifdef FEATURE_WLAN_CCX
2767 case WLAN_CIPHER_SUITE_KRK:
2768 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2769 break;
2770#endif
2771 default:
2772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2773 __func__, params->cipher);
2774 return -EOPNOTSUPP;
2775 }
2776
2777 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2778 __func__, setKey.encType);
2779
2780
2781
2782 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2783#ifdef WLAN_FEATURE_P2P
2784 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2785#endif
2786 )
2787 {
2788
2789
2790 if (
2791#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2792 (!pairwise)
2793#else
2794 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2795#endif
2796 )
2797 {
2798 /* set group key*/
2799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08002800 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002801 __func__, __LINE__);
2802 setKey.keyDirection = eSIR_RX_ONLY;
2803 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2804 }
2805 else
2806 {
2807 /* set pairwise key*/
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2809 "%s- %d: setting pairwise key",
2810 __func__, __LINE__);
2811 setKey.keyDirection = eSIR_TX_RX;
2812 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2813 }
2814
2815 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2816 if( pHostapdState->bssState == BSS_START )
2817 {
2818 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2819
2820 if ( status != eHAL_STATUS_SUCCESS )
2821 {
2822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2823 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2824 __LINE__, status );
2825 }
2826 }
2827
2828 /* Saving WEP keys */
2829 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2830 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2831 {
2832 //Save the wep key in ap context. Issue setkey after the BSS is started.
2833 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2834 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2835 }
2836 else
2837 {
2838 //Save the key in ap context. Issue setkey after the BSS is started.
2839 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2840 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2841 }
2842 }
2843 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2844#ifdef WLAN_FEATURE_P2P
2845 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2846#endif
2847 )
2848 {
2849 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2850 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2851
2852 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
2853
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08002854 pWextState->roamProfile.Keys.defaultIndex = key_index;
2855
2856
Jeff Johnson295189b2012-06-20 16:38:30 -07002857 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
2858 params->key, params->key_len);
2859
2860 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2861
2862 if (!( ( IW_AUTH_KEY_MGMT_802_1X
2863 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2864 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2865 )
2866 &&
2867 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2868 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2869 )
2870 )
2871 {
2872 /* in case of static WEP, macaddr/bssid is not coming from nl80211
2873 * interface, copy bssid for pairwise key and group macaddr for
2874 * group key initialization*/
2875
2876 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2877
2878 pWextState->roamProfile.negotiatedUCEncryptionType =
2879 pHddStaCtx->conn_info.ucEncryptionType =
2880 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
2881 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
2882 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
2883
2884
2885 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2886 "%s: Negotiated encryption type %d", __func__,
2887 pWextState->roamProfile.negotiatedUCEncryptionType);
2888
2889 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
2890 &pWextState->roamProfile, true);
2891 setKey.keyLength = 0;
2892 setKey.keyDirection = eSIR_TX_RX;
2893
2894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2895 if (pairwise)
2896 {
2897#endif
2898 if (mac_addr)
2899 {
2900 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2901 }
2902 else
2903 {
2904 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
2905 * and peerMacAddress in case of IBSS*/
2906 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
2907 {
2908 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
2909 if (HDD_MAX_NUM_IBSS_STA != staidx)
2910 {
2911 vos_mem_copy(setKey.peerMac,
2912 &pHddStaCtx->conn_info.peerMacAddress[staidx],
2913 WNI_CFG_BSSID_LEN);
2914
2915 }
2916 else
2917 {
2918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
2919 __func__);
2920 return -EOPNOTSUPP;
2921 }
2922 }
2923 else
2924 {
2925 vos_mem_copy(setKey.peerMac,
2926 &pHddStaCtx->conn_info.bssId[0],
2927 WNI_CFG_BSSID_LEN);
2928 }
2929 }
2930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2931 }
2932 else
2933 {
2934 /* set group key*/
2935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2936 "%s- %d: setting Group key",
2937 __func__, __LINE__);
2938 setKey.keyDirection = eSIR_RX_ONLY;
2939 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2940 }
2941#endif
2942 }
2943 else if (
2944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2945 (!pairwise)
2946#else
2947 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2948#endif
2949 )
2950 {
2951 /* set group key*/
2952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2953 "%s- %d: setting Group key",
2954 __func__, __LINE__);
2955 setKey.keyDirection = eSIR_RX_ONLY;
2956 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2957 }
2958 else
2959 {
2960 /* set pairwise key*/
2961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2962 "%s- %d: setting pairwise key",
2963 __func__, __LINE__);
2964 setKey.keyDirection = eSIR_TX_RX;
2965 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2966 }
2967
2968 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2969 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2970 __func__, setKey.peerMac[0], setKey.peerMac[1],
2971 setKey.peerMac[2], setKey.peerMac[3],
2972 setKey.peerMac[4], setKey.peerMac[5],
2973 setKey.keyDirection);
2974
2975 vos_status = wlan_hdd_check_ula_done(pAdapter);
2976
2977 if ( vos_status != VOS_STATUS_SUCCESS )
2978 {
2979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2980 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
2981 __LINE__, vos_status );
2982
2983 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
2984
2985 return -EINVAL;
2986
2987 }
2988
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002989#ifdef WLAN_FEATURE_VOWIFI_11R
2990 /* The supplicant may attempt to set the PTK once pre-authentication is done.
2991 Save the key in the UMAC and include it in the ADD BSS request */
2992 /*TODO 11r - is this used?? */
2993 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
2994 if( halStatus == eHAL_STATUS_SUCCESS )
2995 {
2996 return halStatus;
2997 }
2998#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07002999
3000 /* issue set key request to SME*/
3001 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3002 pAdapter->sessionId, &setKey, &roamId );
3003
3004 if ( 0 != status )
3005 {
3006 hddLog(VOS_TRACE_LEVEL_ERROR,
3007 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3008 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3009 return -EINVAL;
3010 }
3011
3012
3013 /* in case of IBSS as there was no information available about WEP keys during
3014 * IBSS join, group key intialized with NULL key, so re-initialize group key
3015 * with correct value*/
3016 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3017 !( ( IW_AUTH_KEY_MGMT_802_1X
3018 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3019 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3020 )
3021 &&
3022 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3023 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3024 )
3025 )
3026 {
3027 setKey.keyDirection = eSIR_RX_ONLY;
3028 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3029
3030 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3031 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3032 __func__, setKey.peerMac[0], setKey.peerMac[1],
3033 setKey.peerMac[2], setKey.peerMac[3],
3034 setKey.peerMac[4], setKey.peerMac[5],
3035 setKey.keyDirection);
3036
3037 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3038 pAdapter->sessionId, &setKey, &roamId );
3039
3040 if ( 0 != status )
3041 {
3042 hddLog(VOS_TRACE_LEVEL_ERROR,
3043 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3044 __func__, status);
3045 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3046 return -EINVAL;
3047 }
3048 }
3049 }
3050
3051 return 0;
3052}
3053
3054/*
3055 * FUNCTION: wlan_hdd_cfg80211_get_key
3056 * This function is used to get the key information
3057 */
3058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3059static int wlan_hdd_cfg80211_get_key(
3060 struct wiphy *wiphy,
3061 struct net_device *ndev,
3062 u8 key_index, bool pairwise,
3063 const u8 *mac_addr, void *cookie,
3064 void (*callback)(void *cookie, struct key_params*)
3065 )
3066#else
3067static int wlan_hdd_cfg80211_get_key(
3068 struct wiphy *wiphy,
3069 struct net_device *ndev,
3070 u8 key_index, const u8 *mac_addr, void *cookie,
3071 void (*callback)(void *cookie, struct key_params*)
3072 )
3073#endif
3074{
3075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3076 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3077 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3078 struct key_params params;
3079
3080 ENTER();
3081
3082 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3083 __func__,pAdapter->device_mode);
3084
3085 memset(&params, 0, sizeof(params));
3086
3087 if (CSR_MAX_NUM_KEY <= key_index)
3088 {
3089 return -EINVAL;
3090 }
3091
3092 switch(pRoamProfile->EncryptionType.encryptionType[0])
3093 {
3094 case eCSR_ENCRYPT_TYPE_NONE:
3095 params.cipher = IW_AUTH_CIPHER_NONE;
3096 break;
3097
3098 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3099 case eCSR_ENCRYPT_TYPE_WEP40:
3100 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3101 break;
3102
3103 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3104 case eCSR_ENCRYPT_TYPE_WEP104:
3105 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3106 break;
3107
3108 case eCSR_ENCRYPT_TYPE_TKIP:
3109 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3110 break;
3111
3112 case eCSR_ENCRYPT_TYPE_AES:
3113 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3114 break;
3115
3116 default:
3117 params.cipher = IW_AUTH_CIPHER_NONE;
3118 break;
3119 }
3120
3121 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3122 params.seq_len = 0;
3123 params.seq = NULL;
3124 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3125 callback(cookie, &params);
3126 return 0;
3127}
3128
3129/*
3130 * FUNCTION: wlan_hdd_cfg80211_del_key
3131 * This function is used to delete the key information
3132 */
3133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3134static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3135 struct net_device *ndev,
3136 u8 key_index,
3137 bool pairwise,
3138 const u8 *mac_addr
3139 )
3140#else
3141static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3142 struct net_device *ndev,
3143 u8 key_index,
3144 const u8 *mac_addr
3145 )
3146#endif
3147{
3148 int status = 0;
3149
3150 //This code needs to be revisited. There is sme_removeKey API, we should
3151 //plan to use that. After the change to use correct index in setkey,
3152 //it is observed that this is invalidating peer
3153 //key index whenever re-key is done. This is affecting data link.
3154 //It should be ok to ignore del_key.
3155#if 0
3156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3157 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3158 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3159 tCsrRoamSetKey setKey;
3160 v_U32_t roamId= 0xFF;
3161
3162 ENTER();
3163
3164 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3165 __func__,pAdapter->device_mode);
3166
3167 if (CSR_MAX_NUM_KEY <= key_index)
3168 {
3169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3170 key_index);
3171
3172 return -EINVAL;
3173 }
3174
3175 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3176 setKey.keyId = key_index;
3177
3178 if (mac_addr)
3179 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3180 else
3181 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3182
3183 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3184
3185 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3186#ifdef WLAN_FEATURE_P2P
3187 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3188#endif
3189 )
3190 {
3191
3192 hdd_hostapd_state_t *pHostapdState =
3193 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3194 if( pHostapdState->bssState == BSS_START)
3195 {
3196 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3197
3198 if ( status != eHAL_STATUS_SUCCESS )
3199 {
3200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3201 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3202 __LINE__, status );
3203 }
3204 }
3205 }
3206 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3207#ifdef WLAN_FEATURE_P2P
3208 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3209#endif
3210 )
3211 {
3212 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3213
3214 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3215
3216 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3217 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3218 __func__, setKey.peerMac[0], setKey.peerMac[1],
3219 setKey.peerMac[2], setKey.peerMac[3],
3220 setKey.peerMac[4], setKey.peerMac[5]);
3221 if(pAdapter->sessionCtx.station.conn_info.connState ==
3222 eConnectionState_Associated)
3223 {
3224 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3225 pAdapter->sessionId, &setKey, &roamId );
3226
3227 if ( 0 != status )
3228 {
3229 hddLog(VOS_TRACE_LEVEL_ERROR,
3230 "%s: sme_RoamSetKey failure, returned %d",
3231 __func__, status);
3232 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3233 return -EINVAL;
3234 }
3235 }
3236 }
3237#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003238 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003239 return status;
3240}
3241
3242/*
3243 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3244 * This function is used to set the default tx key index
3245 */
3246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3247static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3248 struct net_device *ndev,
3249 u8 key_index,
3250 bool unicast, bool multicast)
3251#else
3252static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3253 struct net_device *ndev,
3254 u8 key_index)
3255#endif
3256{
3257 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3258 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3259 int status = 0;
3260 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3261
3262 ENTER();
3263
3264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3265 __func__,pAdapter->device_mode, key_index);
3266
3267 if (CSR_MAX_NUM_KEY <= key_index)
3268 {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3270 key_index);
3271
3272 return -EINVAL;
3273 }
3274
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003275 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3276 {
3277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3278 "%s:LOGP in Progress. Ignore!!!", __func__);
3279 return -EAGAIN;
3280 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003281
3282 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3283#ifdef WLAN_FEATURE_P2P
3284 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3285#endif
3286 )
3287 {
3288 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3289 (eCSR_ENCRYPT_TYPE_TKIP !=
3290 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3291 (eCSR_ENCRYPT_TYPE_AES !=
3292 pWextState->roamProfile.EncryptionType.encryptionType[0])
3293 )
3294 {
3295 /* if default key index is not same as previous one,
3296 * then update the default key index */
3297
3298 tCsrRoamSetKey setKey;
3299 v_U32_t roamId= 0xFF;
3300 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3301
3302 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3303 __func__, key_index);
3304
3305 Keys->defaultIndex = (u8)key_index;
3306 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3307 setKey.keyId = key_index;
3308 setKey.keyLength = Keys->KeyLength[key_index];
3309
3310 vos_mem_copy(&setKey.Key[0],
3311 &Keys->KeyMaterial[key_index][0],
3312 Keys->KeyLength[key_index]);
3313
3314 setKey.keyDirection = eSIR_TX_ONLY;
3315
3316 vos_mem_copy(setKey.peerMac,
3317 &pHddStaCtx->conn_info.bssId[0],
3318 WNI_CFG_BSSID_LEN);
3319
3320 setKey.encType =
3321 pWextState->roamProfile.EncryptionType.encryptionType[0];
3322
3323 /* issue set key request */
3324 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3325 pAdapter->sessionId, &setKey, &roamId );
3326
3327 if ( 0 != status )
3328 {
3329 hddLog(VOS_TRACE_LEVEL_ERROR,
3330 "%s: sme_RoamSetKey failed, returned %d", __func__,
3331 status);
3332 return -EINVAL;
3333 }
3334 }
3335 }
3336
3337 /* In SoftAp mode setting key direction for default mode */
3338 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3339 {
3340 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3341 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3342 (eCSR_ENCRYPT_TYPE_AES !=
3343 pWextState->roamProfile.EncryptionType.encryptionType[0])
3344 )
3345 {
3346 /* Saving key direction for default key index to TX default */
3347 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3348 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3349 }
3350 }
3351
3352 return status;
3353}
3354
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08003355#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07003356/**
3357 * FUNCTION: wlan_hdd_cfg80211_set_channel
3358 * This function is used to set the channel number
3359 */
3360int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
3361 struct ieee80211_channel *chan,
3362 enum nl80211_channel_type channel_type
3363 )
3364{
3365 v_U32_t num_ch = 0;
3366 u32 channel = 0;
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003367 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003368 int freq = chan->center_freq; /* freq is in MHZ */
3369
3370 ENTER();
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003371
3372 if( NULL == dev )
3373 {
3374 hddLog(VOS_TRACE_LEVEL_ERROR,
3375 "%s: Called with dev = NULL.\n", __func__);
3376 return -ENODEV;
3377 }
3378 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003379
3380 hddLog(VOS_TRACE_LEVEL_INFO,
3381 "%s: device_mode = %d freq = %d \n",__func__,
3382 pAdapter->device_mode, chan->center_freq);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07003383 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3384 {
3385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3386 return -EAGAIN;
3387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003388
3389 /*
3390 * Do freq to chan conversion
3391 * TODO: for 11a
3392 */
3393
3394 channel = ieee80211_frequency_to_channel(freq);
3395
3396 /* Check freq range */
3397 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3398 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
3399 {
3400 hddLog(VOS_TRACE_LEVEL_ERROR,
3401 "%s: Channel [%d] is outside valid range from %d to %d\n",
3402 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3403 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3404 return -EINVAL;
3405 }
3406
3407 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3408
3409 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
3410#ifdef WLAN_FEATURE_P2P
3411 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
3412#endif
3413 )
3414 {
3415 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
3416 {
3417 hddLog(VOS_TRACE_LEVEL_ERROR,
3418 "%s: Invalid Channel [%d] \n", __func__, channel);
3419 return -EINVAL;
3420 }
3421 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3422 "%s: set channel to [%d] for device mode =%d",
3423 __func__, channel,pAdapter->device_mode);
3424 }
3425 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3426#ifdef WLAN_FEATURE_P2P
3427 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3428#endif
3429 )
3430 {
3431 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3432 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
3433 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3434
3435 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
3436 {
3437 /* Link is up then return cant set channel*/
3438 hddLog( VOS_TRACE_LEVEL_ERROR,
3439 "%s: IBSS Associated, can't set the channel\n", __func__);
3440 return -EINVAL;
3441 }
3442
3443 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
3444 pHddStaCtx->conn_info.operationChannel = channel;
3445 pRoamProfile->ChannelInfo.ChannelList =
3446 &pHddStaCtx->conn_info.operationChannel;
3447 }
3448 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3449#ifdef WLAN_FEATURE_P2P
3450 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3451#endif
3452 )
3453 {
3454 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
3455
3456 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3457 {
3458 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3459
3460 /* If auto channel selection is configured as enable/ 1 then ignore
3461 channel set by supplicant
3462 */
3463 if ( cfg_param->apAutoChannelSelection )
3464 {
3465 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
3466
3467 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3468 "%s: set channel to auto channel (0) for device mode =%d",
3469 __func__, pAdapter->device_mode);
3470 }
3471 }
3472 }
3473 else
3474 {
3475 hddLog(VOS_TRACE_LEVEL_FATAL,
3476 "%s: Invalid device mode failed to set valid channel", __func__);
3477 return -EINVAL;
3478 }
3479 EXIT();
3480 return 0;
3481}
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08003482#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003483
3484
3485
3486/*
3487 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3488 * This function is used to inform the BSS details to nl80211 interface.
3489 */
3490static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3491 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3492{
3493 struct net_device *dev = pAdapter->dev;
3494 struct wireless_dev *wdev = dev->ieee80211_ptr;
3495 struct wiphy *wiphy = wdev->wiphy;
3496 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3497 int chan_no;
3498 int ie_length;
3499 const char *ie;
3500 unsigned int freq;
3501 struct ieee80211_channel *chan;
3502 int rssi = 0;
3503 struct cfg80211_bss *bss = NULL;
3504
3505 ENTER();
3506
3507 if( NULL == pBssDesc )
3508 {
3509 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3510 return bss;
3511 }
3512
3513 chan_no = pBssDesc->channelId;
3514 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3515 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3516
3517 if( NULL == ie )
3518 {
3519 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3520 return bss;
3521 }
3522
3523#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3524 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3525 {
3526 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3527 }
3528 else
3529 {
3530 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3531 }
3532#else
3533 freq = ieee80211_channel_to_frequency(chan_no);
3534#endif
3535
3536 chan = __ieee80211_get_channel(wiphy, freq);
3537
3538 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3539 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3540 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3541 if (bss == NULL)
3542 {
3543 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3544
3545 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3546 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3547 pBssDesc->capabilityInfo,
3548 pBssDesc->beaconInterval, ie, ie_length,
3549 rssi, GFP_KERNEL ));
3550}
3551 else
3552 {
3553 return bss;
3554 }
3555}
3556
3557
3558
3559/*
3560 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3561 * This function is used to inform the BSS details to nl80211 interface.
3562 */
3563struct cfg80211_bss*
3564wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3565 tSirBssDescription *bss_desc
3566 )
3567{
3568 /*
3569 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3570 already exists in bss data base of cfg80211 for that particular BSS ID.
3571 Using cfg80211_inform_bss_frame to update the bss entry instead of
3572 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3573 now there is no possibility to get the mgmt(probe response) frame from PE,
3574 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3575 cfg80211_inform_bss_frame.
3576 */
3577 struct net_device *dev = pAdapter->dev;
3578 struct wireless_dev *wdev = dev->ieee80211_ptr;
3579 struct wiphy *wiphy = wdev->wiphy;
3580 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003581#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3582 qcom_ie_age *qie_age = NULL;
3583 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3584#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003585 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003586#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003587 const char *ie =
3588 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3589 unsigned int freq;
3590 struct ieee80211_channel *chan;
3591 struct ieee80211_mgmt *mgmt =
3592 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3593 struct cfg80211_bss *bss_status = NULL;
3594 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3595 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003596#ifdef WLAN_OPEN_SOURCE
3597 struct timespec ts;
3598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003599
3600 ENTER();
3601
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003602 if (!mgmt)
3603 return NULL;
3604
Jeff Johnson295189b2012-06-20 16:38:30 -07003605 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003606
3607#ifdef WLAN_OPEN_SOURCE
3608 /* Android does not want the timestamp from the frame.
3609 Instead it wants a monotonic increasing value */
3610 get_monotonic_boottime(&ts);
3611 mgmt->u.probe_resp.timestamp =
3612 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3613#else
3614 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003615 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3616 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003617
3618#endif
3619
Jeff Johnson295189b2012-06-20 16:38:30 -07003620 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3621 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003622
3623#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3624 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3625 /* Assuming this is the last IE, copy at the end */
3626 ie_length -=sizeof(qcom_ie_age);
3627 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3628 qie_age->element_id = QCOM_VENDOR_IE_ID;
3629 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3630 qie_age->oui_1 = QCOM_OUI1;
3631 qie_age->oui_2 = QCOM_OUI2;
3632 qie_age->oui_3 = QCOM_OUI3;
3633 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3634 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3635#endif
3636
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3638
3639 mgmt->frame_control |=
3640 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3641
3642#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3643 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3644 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3645 {
3646 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3647 }
3648 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3649 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3650
3651 {
3652 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3653 }
3654 else
3655 {
3656 kfree(mgmt);
3657 return NULL;
3658 }
3659#else
3660 freq = ieee80211_channel_to_frequency(chan_no);
3661#endif
3662 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003663 /*when the band is changed on the fly using the GUI, three things are done
3664 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
3665 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3666 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3667 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3668 * and discards the channels correponding to previous band and calls back with zero bss results.
3669 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
3670 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3671 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3672 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3673 * So drop the bss and continue to next bss.
3674 */
3675 if(chan == NULL)
3676 {
3677 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3678 return NULL;
3679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 /*To keep the rssi icon of the connected AP in the scan window
3681 *and the rssi icon of the wireless networks in sync
3682 * */
3683 if (( eConnectionState_Associated ==
3684 pAdapter->sessionCtx.station.conn_info.connState ) &&
3685 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3686 pAdapter->sessionCtx.station.conn_info.bssId,
3687 WNI_CFG_BSSID_LEN)))
3688 {
3689 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3690 rssi = (pAdapter->rssi * 100);
3691 }
3692 else
3693 {
3694 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3695 }
3696
3697 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3698 frame_len, rssi, GFP_KERNEL);
3699 kfree(mgmt);
3700 return bss_status;
3701}
3702
3703/*
3704 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3705 * This function is used to update the BSS data base of CFG8011
3706 */
3707struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3708 tCsrRoamInfo *pRoamInfo
3709 )
3710{
3711 tCsrRoamConnectedProfile roamProfile;
3712 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3713 struct cfg80211_bss *bss = NULL;
3714
3715 ENTER();
3716
3717 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3718 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3719
3720 if (NULL != roamProfile.pBssDesc)
3721 {
3722 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3723 &roamProfile);
3724
3725 if (NULL == bss)
3726 {
3727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3728 __func__);
3729 }
3730
3731 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3732 }
3733 else
3734 {
3735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3736 __func__);
3737 }
3738 return bss;
3739}
3740
3741/*
3742 * FUNCTION: wlan_hdd_cfg80211_update_bss
3743 */
3744static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3745 hdd_adapter_t *pAdapter
3746 )
3747{
3748 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3749 tCsrScanResultInfo *pScanResult;
3750 eHalStatus status = 0;
3751 tScanResultHandle pResult;
3752 struct cfg80211_bss *bss_status = NULL;
3753
3754 ENTER();
3755
3756 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3757 {
3758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3759 return -EAGAIN;
3760 }
3761
3762 /*
3763 * start getting scan results and populate cgf80211 BSS database
3764 */
3765 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3766
3767 /* no scan results */
3768 if (NULL == pResult)
3769 {
3770 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3771 return status;
3772 }
3773
3774 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3775
3776 while (pScanResult)
3777 {
3778 /*
3779 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3780 * entry already exists in bss data base of cfg80211 for that
3781 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3782 * bss entry instead of cfg80211_inform_bss, But this call expects
3783 * mgmt packet as input. As of now there is no possibility to get
3784 * the mgmt(probe response) frame from PE, converting bss_desc to
3785 * ieee80211_mgmt(probe response) and passing to c
3786 * fg80211_inform_bss_frame.
3787 * */
3788
3789 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3790 &pScanResult->BssDescriptor);
3791
3792
3793 if (NULL == bss_status)
3794 {
3795 hddLog(VOS_TRACE_LEVEL_INFO,
3796 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3797 }
3798 else
3799 {
3800 cfg80211_put_bss(bss_status);
3801 }
3802
3803 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3804 }
3805
3806 sme_ScanResultPurge(hHal, pResult);
3807
3808 return 0;
3809}
3810
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003811void
3812hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3813{
3814 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003815 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3816 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3817 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003818} /****** end hddPrintMacAddr() ******/
3819
3820void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003821hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003822{
3823 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003824 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3825 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3826 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3827 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003828} /****** end hddPrintPmkId() ******/
3829
3830//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3831//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3832
3833//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3834//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3835
3836#define dump_bssid(bssid) \
3837 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003838 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3839 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3840 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003841 }
3842
3843#define dump_pmkid(pMac, pmkid) \
3844 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003845 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3846 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3847 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003848 }
3849
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003850#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003851/*
3852 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3853 * This function is used to notify the supplicant of a new PMKSA candidate.
3854 */
3855int wlan_hdd_cfg80211_pmksa_candidate_notify(
3856 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3857 int index, bool preauth )
3858{
Jeff Johnsone7245742012-09-05 17:12:55 -07003859#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003860 struct net_device *dev = pAdapter->dev;
3861
3862 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003863 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003864
3865 if( NULL == pRoamInfo )
3866 {
3867 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3868 return -EINVAL;
3869 }
3870
3871 dump_bssid(pRoamInfo->bssid);
3872 cfg80211_pmksa_candidate_notify(dev, index,
3873 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003874#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003875 return 0;
3876}
3877#endif //FEATURE_WLAN_LFR
3878
Jeff Johnson295189b2012-06-20 16:38:30 -07003879/*
3880 * FUNCTION: hdd_cfg80211_scan_done_callback
3881 * scanning callback function, called after finishing scan
3882 *
3883 */
3884static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3885 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3886{
3887 struct net_device *dev = (struct net_device *) pContext;
3888 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3891 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003892 struct cfg80211_scan_request *req = NULL;
3893 int ret = 0;
3894
3895 ENTER();
3896
3897 hddLog(VOS_TRACE_LEVEL_INFO,
3898 "%s called with halHandle = %p, pContext = %p,"
3899 "scanID = %d, returned status = %d\n",
3900 __func__, halHandle, pContext, (int) scanId, (int) status);
3901
3902 //Block on scan req completion variable. Can't wait forever though.
3903 ret = wait_for_completion_interruptible_timeout(
3904 &pScanInfo->scan_req_completion_event,
3905 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3906 if (!ret)
3907 {
3908 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003909 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003910 }
3911
3912 if(pScanInfo->mScanPending != VOS_TRUE)
3913 {
3914 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003915 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 }
3917
3918 /* Check the scanId */
3919 if (pScanInfo->scanId != scanId)
3920 {
3921 hddLog(VOS_TRACE_LEVEL_INFO,
3922 "%s called with mismatched scanId pScanInfo->scanId = %d "
3923 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3924 (int) scanId);
3925 }
3926
Jeff Johnson295189b2012-06-20 16:38:30 -07003927 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3928 pAdapter);
3929
3930 if (0 > ret)
3931 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3932
3933
3934 /* If any client wait scan result through WEXT
3935 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003936 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003937 {
3938 /* The other scan request waiting for current scan finish
3939 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003940 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003941 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003942 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003943 }
3944 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003945 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003946 {
3947 struct net_device *dev = pAdapter->dev;
3948 union iwreq_data wrqu;
3949 int we_event;
3950 char *msg;
3951
3952 memset(&wrqu, '\0', sizeof(wrqu));
3953 we_event = SIOCGIWSCAN;
3954 msg = NULL;
3955 wireless_send_event(dev, we_event, &wrqu, msg);
3956 }
3957 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003958 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003959
3960 /* Get the Scan Req */
3961 req = pAdapter->request;
3962
3963 if (!req)
3964 {
3965 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003966 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003967 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 }
3969
3970 /*
3971 * setting up 0, just in case.
3972 */
3973 req->n_ssids = 0;
3974 req->n_channels = 0;
3975 req->ie = 0;
3976
Jeff Johnson295189b2012-06-20 16:38:30 -07003977 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07003978 /* Scan is no longer pending */
3979 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003980
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07003981 /*
3982 * cfg80211_scan_done informing NL80211 about completion
3983 * of scanning
3984 */
3985 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08003986 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07003987
Jeff Johnsone7245742012-09-05 17:12:55 -07003988allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003989 /* release the wake lock at the end of the scan*/
3990 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07003991
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07003992 /* Acquire wakelock to handle the case where APP's tries to suspend
3993 * immediatly after the driver gets connect request(i.e after scan)
3994 * from supplicant, this result in app's is suspending and not able
3995 * to process the connect request to AP */
3996 hdd_allow_suspend_timeout(100);
3997
Jeff Johnson295189b2012-06-20 16:38:30 -07003998 EXIT();
3999 return 0;
4000}
4001
4002/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004003 * FUNCTION: hdd_isScanAllowed
4004 * Go through each adapter and check if scan allowed
4005 *
4006 */
4007v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4008{
4009 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4010 hdd_station_ctx_t *pHddStaCtx = NULL;
4011 hdd_adapter_t *pAdapter = NULL;
4012 VOS_STATUS status = 0;
4013 v_U8_t staId = 0;
4014 v_U8_t *staMac = NULL;
4015
4016 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4017
4018 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4019 {
4020 pAdapter = pAdapterNode->pAdapter;
4021
4022 if( pAdapter )
4023 {
4024 hddLog(VOS_TRACE_LEVEL_INFO,
4025 "%s: Adapter with device mode %d exists",
4026 __func__, pAdapter->device_mode);
4027 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4028 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4029 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4030 {
4031 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4032 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4033 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4034 {
4035 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4036 hddLog(VOS_TRACE_LEVEL_ERROR,
4037 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4038 "middle of WPS/EAPOL exchange.", __func__,
4039 staMac[0], staMac[1], staMac[2],
4040 staMac[3], staMac[4], staMac[5]);
4041 return VOS_FALSE;
4042 }
4043 }
4044 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4045 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4046 {
4047 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4048 {
4049 if ((pAdapter->aStaInfo[staId].isUsed) &&
4050 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4051 {
4052 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4053
4054 hddLog(VOS_TRACE_LEVEL_ERROR,
4055 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4056 "middle of WPS/EAPOL exchange.", __func__,
4057 staMac[0], staMac[1], staMac[2],
4058 staMac[3], staMac[4], staMac[5]);
4059 return VOS_FALSE;
4060 }
4061 }
4062 }
4063 }
4064 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4065 pAdapterNode = pNext;
4066 }
4067 hddLog(VOS_TRACE_LEVEL_INFO,
4068 "%s: Scan allowed", __func__);
4069 return VOS_TRUE;
4070}
4071
4072/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004073 * FUNCTION: wlan_hdd_cfg80211_scan
4074 * this scan respond to scan trigger and update cfg80211 scan database
4075 * later, scan dump command can be used to recieve scan results
4076 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004077int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4078#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4079 struct net_device *dev,
4080#endif
4081 struct cfg80211_scan_request *request)
4082{
4083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4084 struct net_device *dev = request->wdev->netdev;
4085#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004086 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4087 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4088 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4089 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4090 tCsrScanRequest scanRequest;
4091 tANI_U8 *channelList = NULL, i;
4092 v_U32_t scanId = 0;
4093 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004094 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004095#ifdef WLAN_FEATURE_P2P
4096 v_U8_t* pP2pIe = NULL;
4097#endif
4098
4099 ENTER();
4100
4101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4102 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004103
4104 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4105 (eConnectionState_Connecting ==
4106 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
4107 {
4108 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004109 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4110 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004111 return -EBUSY;
4112 }
4113
Jeff Johnson295189b2012-06-20 16:38:30 -07004114#ifdef WLAN_BTAMP_FEATURE
4115 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004116 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004118 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004119 "%s: No scanning when AMP is on", __func__);
4120 return -EOPNOTSUPP;
4121 }
4122#endif
4123 //Scan on any other interface is not supported.
4124 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
4125 {
4126 hddLog(VOS_TRACE_LEVEL_ERROR,
4127 "%s: Not scanning on device_mode = %d",
4128 __func__, pAdapter->device_mode);
4129 return -EOPNOTSUPP;
4130 }
4131
4132 if (TRUE == pScanInfo->mScanPending)
4133 {
4134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
4135 return -EBUSY;
4136 }
4137
4138 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4139 {
4140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4141 "%s:LOGP in Progress. Ignore!!!", __func__);
4142 return -EAGAIN;
4143 }
4144
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004145 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4146 {
4147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4148 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4149 return -EAGAIN;
4150 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004151 //Don't Allow Scan and return busy if Remain On
4152 //Channel and action frame is pending
4153 //Otherwise Cancel Remain On Channel and allow Scan
4154 //If no action frame pending
4155 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
4156 {
4157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4158 return -EBUSY;
4159 }
4160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4162 {
4163 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004164 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 return -EAGAIN;
4166 }
4167 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4168 {
4169 hddLog(VOS_TRACE_LEVEL_WARN,
4170 "%s: MAX TM Level Scan not allowed", __func__);
4171 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4172 return -EBUSY;
4173 }
4174 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4175
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004176 /* Check if scan is allowed at this point of time.
4177 */
4178 if (!hdd_isScanAllowed(pHddCtx))
4179 {
4180 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4181 return -EBUSY;
4182 }
4183
Jeff Johnson295189b2012-06-20 16:38:30 -07004184 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4185
4186 if (NULL != request)
4187 {
4188 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4189 (int)request->n_ssids);
4190
4191 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4192 * Becasue of this, driver is assuming that this is not wildcard scan and so
4193 * is not aging out the scan results.
4194 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004195 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004196 {
4197 request->n_ssids = 0;
4198 }
4199
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004200 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 {
4202 tCsrSSIDInfo *SsidInfo;
4203 int j;
4204 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4205 /* Allocate num_ssid tCsrSSIDInfo structure */
4206 SsidInfo = scanRequest.SSIDs.SSIDList =
4207 ( tCsrSSIDInfo *)vos_mem_malloc(
4208 request->n_ssids*sizeof(tCsrSSIDInfo));
4209
4210 if(NULL == scanRequest.SSIDs.SSIDList)
4211 {
4212 hddLog(VOS_TRACE_LEVEL_ERROR,
4213 "memory alloc failed SSIDInfo buffer");
4214 return -ENOMEM;
4215 }
4216
4217 /* copy all the ssid's and their length */
4218 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4219 {
4220 /* get the ssid length */
4221 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4222 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4223 SsidInfo->SSID.length);
4224 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4225 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4226 j, SsidInfo->SSID.ssId);
4227 }
4228 /* set the scan type to active */
4229 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4230 }
4231 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4232 {
4233 /* set the scan type to active */
4234 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4235 }
4236 else
4237 {
4238 /*Set the scan type to default type, in this case it is ACTIVE*/
4239 scanRequest.scanType = pScanInfo->scan_mode;
4240 }
4241 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4242 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4243 }
4244 else
4245 {
4246 /* set the scan type to active */
4247 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4248 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4249
4250 /* set min and max channel time to zero */
4251 scanRequest.minChnTime = 0;
4252 scanRequest.maxChnTime = 0;
4253 }
4254
4255 /* set BSSType to default type */
4256 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4257
4258 /*TODO: scan the requested channels only*/
4259
4260 /*Right now scanning all the channels */
4261 if( request )
4262 {
4263 if( request->n_channels )
4264 {
4265 channelList = vos_mem_malloc( request->n_channels );
4266 if( NULL == channelList )
4267 {
4268 status = -ENOMEM;
4269 goto free_mem;
4270 }
4271
4272 for( i = 0 ; i < request->n_channels ; i++ )
4273 channelList[i] = request->channels[i]->hw_value;
4274 }
4275
4276 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4277 scanRequest.ChannelInfo.ChannelList = channelList;
4278
4279 /* set requestType to full scan */
4280 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004281
4282 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4283 * search (Flush on both full scan and social scan but not on single
4284 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4285 */
4286
4287 /* Supplicant does single channel scan after 8-way handshake
4288 * and in that case driver shoudnt flush scan results. If
4289 * driver flushes the scan results here and unfortunately if
4290 * the AP doesnt respond to our probe req then association
4291 * fails which is not desired
4292 */
4293
4294 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4295 {
4296 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4297 pAdapter->sessionId );
4298 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004299
4300 if( request->ie_len )
4301 {
4302 /* save this for future association (join requires this) */
4303 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4304 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4305 pScanInfo->scanAddIE.length = request->ie_len;
4306
4307 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004308 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4309 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004310 )
4311 {
4312 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4313 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4314 }
4315
4316 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4317 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4318
4319#ifdef WLAN_FEATURE_P2P
4320 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4321 request->ie_len);
4322 if (pP2pIe != NULL)
4323 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004324#ifdef WLAN_FEATURE_P2P_DEBUG
4325 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4326 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4327 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4328 {
4329 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4330 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4331 "Go nego completed to Connection is started");
4332 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4333 "for 8way Handshake");
4334 }
4335 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4336 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4337 {
4338 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4339 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4340 "Disconnected state to Connection is started");
4341 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4342 "for 4way Handshake");
4343 }
4344#endif
4345
Jeff Johnsone7245742012-09-05 17:12:55 -07004346 /* no_cck will be set during p2p find to disable 11b rates */
4347 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004348 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004349 hddLog(VOS_TRACE_LEVEL_INFO,
4350 "%s: This is a P2P Search", __func__);
4351 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004352
Jeff Johnsone7245742012-09-05 17:12:55 -07004353 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4354 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004355 /* set requestType to P2P Discovery */
4356 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004357 }
4358
4359 /*
4360 Skip Dfs Channel in case of P2P Search
4361 if it is set in ini file
4362 */
4363 if(cfg_param->skipDfsChnlInP2pSearch)
4364 {
4365 scanRequest.skipDfsChnlInP2pSearch = 1;
4366 }
4367 else
4368 {
4369 scanRequest.skipDfsChnlInP2pSearch = 0;
4370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004371
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 }
4373 }
4374#endif
4375 }
4376 }
4377
4378 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4379
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004380 /* acquire the wakelock to avoid the apps suspend during the scan. To
4381 * address the following issues.
4382 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4383 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4384 * for long time, this result in apps running at full power for long time.
4385 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4386 * be stuck in full power because of resume BMPS
4387 */
4388 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004389
4390 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004391 pAdapter->sessionId, &scanRequest, &scanId,
4392 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004393
Jeff Johnson295189b2012-06-20 16:38:30 -07004394 if (eHAL_STATUS_SUCCESS != status)
4395 {
4396 hddLog(VOS_TRACE_LEVEL_ERROR,
4397 "%s: sme_ScanRequest returned error %d", __func__, status);
4398 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004399 if(eHAL_STATUS_RESOURCES == status)
4400 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004401 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 -07004402 status = -EBUSY;
4403 } else {
4404 status = -EIO;
4405 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004406 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004407 goto free_mem;
4408 }
4409
4410 pScanInfo->mScanPending = TRUE;
4411 pAdapter->request = request;
4412 pScanInfo->scanId = scanId;
4413
4414 complete(&pScanInfo->scan_req_completion_event);
4415
4416free_mem:
4417 if( scanRequest.SSIDs.SSIDList )
4418 {
4419 vos_mem_free(scanRequest.SSIDs.SSIDList);
4420 }
4421
4422 if( channelList )
4423 vos_mem_free( channelList );
4424
4425 EXIT();
4426
4427 return status;
4428}
4429
4430/*
4431 * FUNCTION: wlan_hdd_cfg80211_connect_start
4432 * This function is used to start the association process
4433 */
4434int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004435 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004436{
4437 int status = 0;
4438 hdd_wext_state_t *pWextState;
4439 v_U32_t roamId;
4440 tCsrRoamProfile *pRoamProfile;
4441 eMib_dot11DesiredBssType connectedBssType;
4442 eCsrAuthType RSNAuthType;
4443
4444 ENTER();
4445
4446 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4447
4448 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4449 {
4450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4451 return -EINVAL;
4452 }
4453
4454 pRoamProfile = &pWextState->roamProfile;
4455
4456 if (pRoamProfile)
4457 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004458 int ret = 0;
4459 hdd_station_ctx_t *pHddStaCtx;
4460 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4461 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4462
4463 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4464 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4465 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004466 {
4467 /* Issue disconnect to CSR */
4468 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4469 if( eHAL_STATUS_SUCCESS ==
4470 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4471 pAdapter->sessionId,
4472 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4473 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004474 ret = wait_for_completion_interruptible_timeout(
4475 &pAdapter->disconnect_comp_var,
4476 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4477 if (0 == ret)
4478 {
4479 VOS_ASSERT(0);
4480 }
4481 }
4482 }
4483 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4484 {
4485 ret = wait_for_completion_interruptible_timeout(
4486 &pAdapter->disconnect_comp_var,
4487 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4488 if (0 == ret)
4489 {
4490 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004491 }
4492 }
4493
4494 if (HDD_WMM_USER_MODE_NO_QOS ==
4495 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4496 {
4497 /*QoS not enabled in cfg file*/
4498 pRoamProfile->uapsd_mask = 0;
4499 }
4500 else
4501 {
4502 /*QoS enabled, update uapsd mask from cfg file*/
4503 pRoamProfile->uapsd_mask =
4504 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4505 }
4506
4507 pRoamProfile->SSIDs.numOfSSIDs = 1;
4508 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4509 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4510 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4511 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4512 ssid, ssid_len);
4513
4514 if (bssid)
4515 {
4516 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4517 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4518 WNI_CFG_BSSID_LEN);
4519 /* Save BSSID in seperate variable as well, as RoamProfile
4520 BSSID is getting zeroed out in the association process. And in
4521 case of join failure we should send valid BSSID to supplicant
4522 */
4523 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4524 WNI_CFG_BSSID_LEN);
4525 }
4526
4527 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4528 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4529 {
4530 /*set gen ie*/
4531 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4532 /*set auth*/
4533 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4534 }
4535 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4536 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4537 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4538 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4539 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4540 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4541 )
4542 {
4543 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4544 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4545 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4546 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4547 eCSR_AUTH_TYPE_AUTOSWITCH;
4548 pWextState->roamProfile.AuthType.authType[0] =
4549 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4550 }
4551#ifdef FEATURE_WLAN_WAPI
4552 if (pAdapter->wapi_info.nWapiMode)
4553 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004554 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 switch (pAdapter->wapi_info.wapiAuthMode)
4556 {
4557 case WAPI_AUTH_MODE_PSK:
4558 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004559 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004560 pAdapter->wapi_info.wapiAuthMode);
4561 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4562 break;
4563 }
4564 case WAPI_AUTH_MODE_CERT:
4565 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004566 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004567 pAdapter->wapi_info.wapiAuthMode);
4568 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4569 break;
4570 }
4571 } // End of switch
4572 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4573 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4574 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004575 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004576 pRoamProfile->AuthType.numEntries = 1;
4577 pRoamProfile->EncryptionType.numEntries = 1;
4578 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4579 pRoamProfile->mcEncryptionType.numEntries = 1;
4580 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4581 }
4582 }
4583#endif /* FEATURE_WLAN_WAPI */
4584 pRoamProfile->csrPersona = pAdapter->device_mode;
4585
Jeff Johnson32d95a32012-09-10 13:15:23 -07004586 if( operatingChannel )
4587 {
4588 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4589 pRoamProfile->ChannelInfo.numOfChannels = 1;
4590 }
4591
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004592 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4593 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4594 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4595 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004596 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4597 */
4598 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4599 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4600 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004601
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4603 pAdapter->sessionId, pRoamProfile, &roamId);
4604
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004605 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304606 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4607
4608 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4610 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4611 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304612 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004613 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304614 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004615
4616 pRoamProfile->ChannelInfo.ChannelList = NULL;
4617 pRoamProfile->ChannelInfo.numOfChannels = 0;
4618
Jeff Johnson295189b2012-06-20 16:38:30 -07004619 }
4620 else
4621 {
4622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4623 return -EINVAL;
4624 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004625 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004626 return status;
4627}
4628
4629/*
4630 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4631 * This function is used to set the authentication type (OPEN/SHARED).
4632 *
4633 */
4634static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4635 enum nl80211_auth_type auth_type)
4636{
4637 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4638 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4639
4640 ENTER();
4641
4642 /*set authentication type*/
4643 switch (auth_type)
4644 {
4645 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4646 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004647#ifdef WLAN_FEATURE_VOWIFI_11R
4648 case NL80211_AUTHTYPE_FT:
4649#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 hddLog(VOS_TRACE_LEVEL_INFO,
4651 "%s: set authentication type to OPEN", __func__);
4652 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4653 break;
4654
4655 case NL80211_AUTHTYPE_SHARED_KEY:
4656 hddLog(VOS_TRACE_LEVEL_INFO,
4657 "%s: set authentication type to SHARED", __func__);
4658 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4659 break;
4660#ifdef FEATURE_WLAN_CCX
4661 case NL80211_AUTHTYPE_NETWORK_EAP:
4662 hddLog(VOS_TRACE_LEVEL_INFO,
4663 "%s: set authentication type to CCKM WPA", __func__);
4664 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4665 break;
4666#endif
4667
4668
4669 default:
4670 hddLog(VOS_TRACE_LEVEL_ERROR,
4671 "%s: Unsupported authentication type %d", __func__,
4672 auth_type);
4673 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4674 return -EINVAL;
4675 }
4676
4677 pWextState->roamProfile.AuthType.authType[0] =
4678 pHddStaCtx->conn_info.authType;
4679 return 0;
4680}
4681
4682/*
4683 * FUNCTION: wlan_hdd_set_akm_suite
4684 * This function is used to set the key mgmt type(PSK/8021x).
4685 *
4686 */
4687static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4688 u32 key_mgmt
4689 )
4690{
4691 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4692 ENTER();
4693
4694 /*set key mgmt type*/
4695 switch(key_mgmt)
4696 {
4697 case WLAN_AKM_SUITE_PSK:
4698 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4699 __func__);
4700 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4701 break;
4702
4703 case WLAN_AKM_SUITE_8021X:
4704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4705 __func__);
4706 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4707 break;
4708#ifdef FEATURE_WLAN_CCX
4709#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4710#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4711 case WLAN_AKM_SUITE_CCKM:
4712 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4713 __func__);
4714 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4715 break;
4716#endif
4717
4718 default:
4719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4720 __func__, key_mgmt);
4721 return -EINVAL;
4722
4723 }
4724 return 0;
4725}
4726
4727/*
4728 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4729 * This function is used to set the encryption type
4730 * (NONE/WEP40/WEP104/TKIP/CCMP).
4731 */
4732static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4733 u32 cipher,
4734 bool ucast
4735 )
4736{
4737 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4738 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4739 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4740
4741 ENTER();
4742
4743 if (!cipher)
4744 {
4745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4746 __func__, cipher);
4747 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4748 }
4749 else
4750 {
4751
4752 /*set encryption method*/
4753 switch (cipher)
4754 {
4755 case IW_AUTH_CIPHER_NONE:
4756 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4757 break;
4758
4759 case WLAN_CIPHER_SUITE_WEP40:
4760 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4761 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4762 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4763 else
4764 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4765 break;
4766
4767 case WLAN_CIPHER_SUITE_WEP104:
4768 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4769 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4770 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4771 else
4772 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4773 break;
4774
4775 case WLAN_CIPHER_SUITE_TKIP:
4776 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4777 break;
4778
4779 case WLAN_CIPHER_SUITE_CCMP:
4780 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4781 break;
4782#ifdef FEATURE_WLAN_WAPI
4783 case WLAN_CIPHER_SUITE_SMS4:
4784 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4785 break;
4786#endif
4787
4788#ifdef FEATURE_WLAN_CCX
4789 case WLAN_CIPHER_SUITE_KRK:
4790 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4791 break;
4792#endif
4793 default:
4794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4795 __func__, cipher);
4796 return -EOPNOTSUPP;
4797 }
4798 }
4799
4800 if (ucast)
4801 {
4802 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4803 __func__, encryptionType);
4804 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4805 pWextState->roamProfile.EncryptionType.numEntries = 1;
4806 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4807 encryptionType;
4808 }
4809 else
4810 {
4811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4812 __func__, encryptionType);
4813 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4814 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4815 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4816 }
4817
4818 return 0;
4819}
4820
4821
4822/*
4823 * FUNCTION: wlan_hdd_cfg80211_set_ie
4824 * This function is used to parse WPA/RSN IE's.
4825 */
4826int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4827 u8 *ie,
4828 size_t ie_len
4829 )
4830{
4831 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4832 u8 *genie = ie;
4833 v_U16_t remLen = ie_len;
4834#ifdef FEATURE_WLAN_WAPI
4835 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4836 u16 *tmp;
4837 v_U16_t akmsuiteCount;
4838 int *akmlist;
4839#endif
4840 ENTER();
4841
4842 /* clear previous assocAddIE */
4843 pWextState->assocAddIE.length = 0;
4844 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4845
4846 while (remLen >= 2)
4847 {
4848 v_U16_t eLen = 0;
4849 v_U8_t elementId;
4850 elementId = *genie++;
4851 eLen = *genie++;
4852 remLen -= 2;
4853
4854 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4855 __func__, elementId, eLen);
4856
4857 switch ( elementId )
4858 {
4859 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004860 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 -07004861 {
4862 hddLog(VOS_TRACE_LEVEL_ERROR,
4863 "%s: Invalid WPA IE", __func__);
4864 return -EINVAL;
4865 }
4866 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4867 {
4868 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4869 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4870 __func__, eLen + 2);
4871
4872 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4873 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004874 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4875 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004876 VOS_ASSERT(0);
4877 return -ENOMEM;
4878 }
4879 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4880 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4881 pWextState->assocAddIE.length += eLen + 2;
4882
4883 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4884 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4885 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4886 }
4887 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4888 {
4889 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4890 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4891 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4892 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4893 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4894 }
4895#ifdef WLAN_FEATURE_P2P
4896 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4897 P2P_OUI_TYPE_SIZE))
4898 /*Consider P2P IE, only for P2P Client */
4899 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4900 {
4901 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4902 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4903 __func__, eLen + 2);
4904
4905 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4906 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004907 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4908 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004909 VOS_ASSERT(0);
4910 return -ENOMEM;
4911 }
4912 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4913 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4914 pWextState->assocAddIE.length += eLen + 2;
4915
4916 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4917 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4918 }
4919#endif
4920#ifdef WLAN_FEATURE_WFD
4921 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4922 WFD_OUI_TYPE_SIZE))
4923 /*Consider WFD IE, only for P2P Client */
4924 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4925 {
4926 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4927 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4928 __func__, eLen + 2);
4929
4930 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4931 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004932 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4933 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 VOS_ASSERT(0);
4935 return -ENOMEM;
4936 }
4937 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4938 // WPS IE + P2P IE + WFD IE
4939 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4940 pWextState->assocAddIE.length += eLen + 2;
4941
4942 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4943 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4944 }
4945#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004946 /* Appending HS 2.0 Indication Element in Assiciation Request */
4947 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004948 HS20_OUI_TYPE_SIZE)) )
4949 {
4950 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4951 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4952 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004953
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004954 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4955 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004956 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4957 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004958 VOS_ASSERT(0);
4959 return -ENOMEM;
4960 }
4961 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4962 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004963
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004964 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4965 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4966 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004967
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 break;
4969 case DOT11F_EID_RSN:
4970 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4971 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4972 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4973 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4974 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4975 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004976 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4977 case DOT11F_EID_EXTCAP:
4978 {
4979 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4980 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
4981 __func__, eLen + 2);
4982
4983 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4984 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004985 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4986 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004987 VOS_ASSERT(0);
4988 return -ENOMEM;
4989 }
4990 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4991 pWextState->assocAddIE.length += eLen + 2;
4992
4993 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4994 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4995 break;
4996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004997#ifdef FEATURE_WLAN_WAPI
4998 case WLAN_EID_WAPI:
4999 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5000 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5001 pAdapter->wapi_info.nWapiMode);
5002 tmp = (u16 *)ie;
5003 tmp = tmp + 2; // Skip element Id and Len, Version
5004 akmsuiteCount = WPA_GET_LE16(tmp);
5005 tmp = tmp + 1;
5006 akmlist = (int *)(tmp);
5007 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5008 {
5009 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5010 }
5011 else
5012 {
5013 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5014 VOS_ASSERT(0);
5015 return -EINVAL;
5016 }
5017
5018 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5019 {
5020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005021 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5023 }
5024 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5025 {
5026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005027 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5029 }
5030 break;
5031#endif
5032 default:
5033 hddLog (VOS_TRACE_LEVEL_ERROR,
5034 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005035 /* when Unknown IE is received we should break and continue
5036 * to the next IE in the buffer instead we were returning
5037 * so changing this to break */
5038 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 }
5040 genie += eLen;
5041 remLen -= eLen;
5042 }
5043 EXIT();
5044 return 0;
5045}
5046
5047/*
5048 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5049 * This function is used to initialize the security
5050 * parameters during connect operation.
5051 */
5052int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5053 struct cfg80211_connect_params *req
5054 )
5055{
5056 int status = 0;
5057 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5058 ENTER();
5059
5060 /*set wpa version*/
5061 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5062
5063 if (req->crypto.wpa_versions)
5064 {
5065 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5066 && ( (req->ie_len)
5067 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5068 // Make sure that it is including a WPA IE.
5069 /* Currently NL is putting WPA version 1 even for open,
5070 * since p2p ie is also put in same buffer.
5071 * */
5072 {
5073 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5074 }
5075 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5076 {
5077 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5078 }
5079 }
5080
5081 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5082 pWextState->wpaVersion);
5083
5084 /*set authentication type*/
5085 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5086
5087 if (0 > status)
5088 {
5089 hddLog(VOS_TRACE_LEVEL_ERROR,
5090 "%s: failed to set authentication type ", __func__);
5091 return status;
5092 }
5093
5094 /*set key mgmt type*/
5095 if (req->crypto.n_akm_suites)
5096 {
5097 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5098 if (0 > status)
5099 {
5100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5101 __func__);
5102 return status;
5103 }
5104 }
5105
5106 /*set pairwise cipher type*/
5107 if (req->crypto.n_ciphers_pairwise)
5108 {
5109 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5110 req->crypto.ciphers_pairwise[0], true);
5111 if (0 > status)
5112 {
5113 hddLog(VOS_TRACE_LEVEL_ERROR,
5114 "%s: failed to set unicast cipher type", __func__);
5115 return status;
5116 }
5117 }
5118 else
5119 {
5120 /*Reset previous cipher suite to none*/
5121 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5122 if (0 > status)
5123 {
5124 hddLog(VOS_TRACE_LEVEL_ERROR,
5125 "%s: failed to set unicast cipher type", __func__);
5126 return status;
5127 }
5128 }
5129
5130 /*set group cipher type*/
5131 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5132 false);
5133
5134 if (0 > status)
5135 {
5136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5137 __func__);
5138 return status;
5139 }
5140
5141 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5142 if (req->ie_len)
5143 {
5144 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5145 if ( 0 > status)
5146 {
5147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5148 __func__);
5149 return status;
5150 }
5151 }
5152
5153 /*incase of WEP set default key information*/
5154 if (req->key && req->key_len)
5155 {
5156 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5157 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5158 )
5159 {
5160 if ( IW_AUTH_KEY_MGMT_802_1X
5161 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5162 {
5163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5164 __func__);
5165 return -EOPNOTSUPP;
5166 }
5167 else
5168 {
5169 u8 key_len = req->key_len;
5170 u8 key_idx = req->key_idx;
5171
5172 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5173 && (CSR_MAX_NUM_KEY > key_idx)
5174 )
5175 {
5176 hddLog(VOS_TRACE_LEVEL_INFO,
5177 "%s: setting default wep key, key_idx = %hu key_len %hu",
5178 __func__, key_idx, key_len);
5179 vos_mem_copy(
5180 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5181 req->key, key_len);
5182 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5183 (u8)key_len;
5184 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5185 }
5186 }
5187 }
5188 }
5189
5190 return status;
5191}
5192
5193/*
5194 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5195 * This function is used to initialize the security
5196 * parameters during connect operation.
5197 */
5198static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5199 struct net_device *ndev,
5200 struct cfg80211_connect_params *req
5201 )
5202{
5203 int status = 0;
5204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5205 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5206 hdd_context_t *pHddCtx = NULL;
5207
5208 ENTER();
5209
5210 hddLog(VOS_TRACE_LEVEL_INFO,
5211 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5212
5213 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5214 {
5215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5216 "%s:LOGP in Progress. Ignore!!!", __func__);
5217 return -EAGAIN;
5218 }
5219
5220#ifdef WLAN_BTAMP_FEATURE
5221 //Infra connect not supported when AMP traffic is on.
5222 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5223 {
5224 hddLog(VOS_TRACE_LEVEL_ERROR,
5225 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005226 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005227 }
5228#endif
5229 /*initialise security parameters*/
5230 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5231
5232 if ( 0 > status)
5233 {
5234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5235 __func__);
5236 return status;
5237 }
5238
5239 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005240 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005241 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5242 (vos_concurrent_sessions_running()))
5243 {
5244 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5245
5246 if (NULL != pVosContext)
5247 {
5248 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5249 if(NULL != pHddCtx)
5250 {
5251 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5252 }
5253 }
5254 }
5255
Mohit Khanna765234a2012-09-11 15:08:35 -07005256 if ( req->channel )
5257 {
5258 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5259 req->ssid_len, req->bssid,
5260 req->channel->hw_value);
5261 }
5262 else
5263 {
5264 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5265 req->ssid_len, req->bssid,
5266 0);
5267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005268
5269 if (0 > status)
5270 {
5271 //ReEnable BMPS if disabled
5272 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5273 (NULL != pHddCtx))
5274 {
5275 //ReEnable Bmps and Imps back
5276 hdd_enable_bmps_imps(pHddCtx);
5277 }
5278
5279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5280 return status;
5281 }
5282 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5283 EXIT();
5284 return status;
5285}
5286
5287
5288/*
5289 * FUNCTION: wlan_hdd_cfg80211_disconnect
5290 * This function is used to issue a disconnect request to SME
5291 */
5292static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5293 struct net_device *dev,
5294 u16 reason
5295 )
5296{
5297 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5298 tCsrRoamProfile *pRoamProfile =
5299 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5300 int status = 0;
5301 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5302
5303 ENTER();
5304
5305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5306 __func__,pAdapter->device_mode);
5307
5308 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5309 __func__, reason);
5310
5311 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5312 {
5313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5314 "%s:LOGP in Progress. Ignore!!!",__func__);
5315 return -EAGAIN;
5316 }
5317 if (NULL != pRoamProfile)
5318 {
5319 /*issue disconnect request to SME, if station is in connected state*/
5320 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5321 {
5322 eCsrRoamDisconnectReason reasonCode =
5323 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5324 switch(reason)
5325 {
5326 case WLAN_REASON_MIC_FAILURE:
5327 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5328 break;
5329
5330 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5331 case WLAN_REASON_DISASSOC_AP_BUSY:
5332 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5333 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5334 break;
5335
5336 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5337 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5338 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5339 break;
5340
5341 case WLAN_REASON_DEAUTH_LEAVING:
5342 default:
5343 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5344 break;
5345 }
5346 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5347 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5348 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5349
5350 /*issue disconnect*/
5351 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5352 pAdapter->sessionId, reasonCode);
5353
5354 if ( 0 != status)
5355 {
5356 hddLog(VOS_TRACE_LEVEL_ERROR,
5357 "%s csrRoamDisconnect failure, returned %d \n",
5358 __func__, (int)status );
5359 return -EINVAL;
5360 }
5361
5362 wait_for_completion_interruptible_timeout(
5363 &pAdapter->disconnect_comp_var,
5364 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5365
5366
5367 /*stop tx queues*/
5368 netif_tx_disable(dev);
5369 netif_carrier_off(dev);
5370 }
5371 }
5372 else
5373 {
5374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5375 }
5376
5377 return status;
5378}
5379
5380/*
5381 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5382 * This function is used to initialize the security
5383 * settings in IBSS mode.
5384 */
5385static int wlan_hdd_cfg80211_set_privacy_ibss(
5386 hdd_adapter_t *pAdapter,
5387 struct cfg80211_ibss_params *params
5388 )
5389{
5390 int status = 0;
5391 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5392 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5393 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5394
5395 ENTER();
5396
5397 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5398
5399 if (params->ie_len && ( NULL != params->ie) )
5400 {
5401 if (WLAN_EID_RSN == params->ie[0])
5402 {
5403 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5404 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5405 }
5406 else
5407 {
5408 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5409 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5410 }
5411 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5412
5413 if (0 > status)
5414 {
5415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5416 __func__);
5417 return status;
5418 }
5419 }
5420
5421 pWextState->roamProfile.AuthType.authType[0] =
5422 pHddStaCtx->conn_info.authType =
5423 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5424
5425 if (params->privacy)
5426 {
5427 /* Security enabled IBSS, At this time there is no information available
5428 * about the security paramters, so initialise the encryption type to
5429 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5430 * The correct security parameters will be updated later in
5431 * wlan_hdd_cfg80211_add_key */
5432 /* Hal expects encryption type to be set inorder
5433 *enable privacy bit in beacons */
5434
5435 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5436 }
5437
5438 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5439 pWextState->roamProfile.EncryptionType.numEntries = 1;
5440 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5441
5442 return status;
5443}
5444
5445/*
5446 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5447 * This function is used to create/join an IBSS
5448 */
5449static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5450 struct net_device *dev,
5451 struct cfg80211_ibss_params *params
5452 )
5453{
5454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5455 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5456 tCsrRoamProfile *pRoamProfile;
5457 int status;
5458 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5459
5460 ENTER();
5461
5462 hddLog(VOS_TRACE_LEVEL_INFO,
5463 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5464
5465 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5466 {
5467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5468 "%s:LOGP in Progress. Ignore!!!", __func__);
5469 return -EAGAIN;
5470 }
5471
5472 if (NULL == pWextState)
5473 {
5474 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5475 __func__);
5476 return -EIO;
5477 }
5478
5479 pRoamProfile = &pWextState->roamProfile;
5480
5481 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5482 {
5483 hddLog (VOS_TRACE_LEVEL_ERROR,
5484 "%s Interface type is not set to IBSS \n", __func__);
5485 return -EINVAL;
5486 }
5487
5488 /* Set Channel */
5489 if (NULL != params->channel)
5490 {
5491 u8 channelNum;
5492 if (IEEE80211_BAND_5GHZ == params->channel->band)
5493 {
5494 hddLog(VOS_TRACE_LEVEL_ERROR,
5495 "%s: IBSS join is called with unsupported band %d",
5496 __func__, params->channel->band);
5497 return -EOPNOTSUPP;
5498 }
5499
5500 /* Get channel number */
5501 channelNum =
5502 ieee80211_frequency_to_channel(params->channel->center_freq);
5503
5504 /*TODO: use macro*/
5505 if (14 >= channelNum)
5506 {
5507 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5508 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5509 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5510 int indx;
5511
5512 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5513 validChan, &numChans))
5514 {
5515 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5516 __func__);
5517 return -EOPNOTSUPP;
5518 }
5519
5520 for (indx = 0; indx < numChans; indx++)
5521 {
5522 if (channelNum == validChan[indx])
5523 {
5524 break;
5525 }
5526 }
5527 if (indx >= numChans)
5528 {
5529 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5530 __func__, channelNum);
5531 return -EINVAL;
5532 }
5533 /* Set the Operational Channel */
5534 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5535 channelNum);
5536 pRoamProfile->ChannelInfo.numOfChannels = 1;
5537 pHddStaCtx->conn_info.operationChannel = channelNum;
5538 pRoamProfile->ChannelInfo.ChannelList =
5539 &pHddStaCtx->conn_info.operationChannel;
5540 }
5541 else
5542 {
5543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5544 __func__, channelNum);
5545 return -EINVAL;
5546 }
5547 }
5548
5549 /* Initialize security parameters */
5550 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5551 if (status < 0)
5552 {
5553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5554 __func__);
5555 return status;
5556 }
5557
5558 /* Issue connect start */
5559 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005560 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005561
5562 if (0 > status)
5563 {
5564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5565 return status;
5566 }
5567
5568 return 0;
5569}
5570
5571/*
5572 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5573 * This function is used to leave an IBSS
5574 */
5575static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5576 struct net_device *dev
5577 )
5578{
5579 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5580 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5581 tCsrRoamProfile *pRoamProfile;
5582
5583 ENTER();
5584
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005585 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5586 {
5587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5588 "%s:LOGP in Progress. Ignore!!!", __func__);
5589 return -EAGAIN;
5590 }
5591
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5593 if (NULL == pWextState)
5594 {
5595 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5596 __func__);
5597 return -EIO;
5598 }
5599
5600 pRoamProfile = &pWextState->roamProfile;
5601
5602 /* Issue disconnect only if interface type is set to IBSS */
5603 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5604 {
5605 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5606 __func__);
5607 return -EINVAL;
5608 }
5609
5610 /* Issue Disconnect request */
5611 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5612 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5613 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5614
5615 return 0;
5616}
5617
5618/*
5619 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5620 * This function is used to set the phy parameters
5621 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5622 */
5623static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5624 u32 changed)
5625{
5626 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5627 tHalHandle hHal = pHddCtx->hHal;
5628
5629 ENTER();
5630
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005631 if ( pHddCtx->isLogpInProgress )
5632 {
5633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5634 "%s:LOGP in Progress. Ignore!!!", __func__);
5635 return -EAGAIN;
5636 }
5637
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5639 {
5640 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5641 WNI_CFG_RTS_THRESHOLD_STAMAX :
5642 wiphy->rts_threshold;
5643
5644 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5645 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5646 {
5647 hddLog(VOS_TRACE_LEVEL_ERROR,
5648 "%s: Invalid RTS Threshold value %hu",
5649 __func__, rts_threshold);
5650 return -EINVAL;
5651 }
5652
5653 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5654 rts_threshold, ccmCfgSetCallback,
5655 eANI_BOOLEAN_TRUE))
5656 {
5657 hddLog(VOS_TRACE_LEVEL_ERROR,
5658 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5659 __func__, rts_threshold);
5660 return -EIO;
5661 }
5662
5663 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5664 rts_threshold);
5665 }
5666
5667 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5668 {
5669 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5670 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5671 wiphy->frag_threshold;
5672
5673 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5674 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5675 {
5676 hddLog(VOS_TRACE_LEVEL_ERROR,
5677 "%s: Invalid frag_threshold value %hu", __func__,
5678 frag_threshold);
5679 return -EINVAL;
5680 }
5681
5682 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5683 frag_threshold, ccmCfgSetCallback,
5684 eANI_BOOLEAN_TRUE))
5685 {
5686 hddLog(VOS_TRACE_LEVEL_ERROR,
5687 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5688 __func__, frag_threshold);
5689 return -EIO;
5690 }
5691
5692 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5693 frag_threshold);
5694 }
5695
5696 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5697 || (changed & WIPHY_PARAM_RETRY_LONG))
5698 {
5699 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5700 wiphy->retry_short :
5701 wiphy->retry_long;
5702
5703 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5704 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5705 {
5706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5707 __func__, retry_value);
5708 return -EINVAL;
5709 }
5710
5711 if (changed & WIPHY_PARAM_RETRY_SHORT)
5712 {
5713 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5714 retry_value, ccmCfgSetCallback,
5715 eANI_BOOLEAN_TRUE))
5716 {
5717 hddLog(VOS_TRACE_LEVEL_ERROR,
5718 "%s: ccmCfgSetInt failed for long retry count %hu",
5719 __func__, retry_value);
5720 return -EIO;
5721 }
5722 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5723 __func__, retry_value);
5724 }
5725 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5726 {
5727 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5728 retry_value, ccmCfgSetCallback,
5729 eANI_BOOLEAN_TRUE))
5730 {
5731 hddLog(VOS_TRACE_LEVEL_ERROR,
5732 "%s: ccmCfgSetInt failed for short retry count %hu",
5733 __func__, retry_value);
5734 return -EIO;
5735 }
5736 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5737 __func__, retry_value);
5738 }
5739 }
5740
5741 return 0;
5742}
5743
5744/*
5745 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5746 * This function is used to set the txpower
5747 */
5748static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5749#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5750 enum tx_power_setting type,
5751#else
5752 enum nl80211_tx_power_setting type,
5753#endif
5754 int dbm)
5755{
5756 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5757 tHalHandle hHal = pHddCtx->hHal;
5758 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5759 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5760
5761 ENTER();
5762
5763 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5764 dbm, ccmCfgSetCallback,
5765 eANI_BOOLEAN_TRUE))
5766 {
5767 hddLog(VOS_TRACE_LEVEL_ERROR,
5768 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5769 return -EIO;
5770 }
5771
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005772 if ( pHddCtx->isLogpInProgress )
5773 {
5774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5775 "%s:LOGP in Progress. Ignore!!!", __func__);
5776 return -EAGAIN;
5777 }
5778
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5780 dbm);
5781
5782 switch(type)
5783 {
5784 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5785 /* Fall through */
5786 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5787 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5788 {
5789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5790 __func__);
5791 return -EIO;
5792 }
5793 break;
5794 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5796 __func__);
5797 return -EOPNOTSUPP;
5798 break;
5799 default:
5800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5801 __func__, type);
5802 return -EIO;
5803 }
5804
5805 return 0;
5806}
5807
5808/*
5809 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5810 * This function is used to read the txpower
5811 */
5812static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5813{
5814
5815 hdd_adapter_t *pAdapter;
5816 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5817
Jeff Johnsone7245742012-09-05 17:12:55 -07005818 ENTER();
5819
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 if (NULL == pHddCtx)
5821 {
5822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5823 *dbm = 0;
5824 return -ENOENT;
5825 }
5826
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005827 if ( pHddCtx->isLogpInProgress )
5828 {
5829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5830 "%s:LOGP in Progress. Ignore!!!", __func__);
5831 return -EAGAIN;
5832 }
5833
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5835 if (NULL == pAdapter)
5836 {
5837 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5838 return -ENOENT;
5839 }
5840
5841 wlan_hdd_get_classAstats(pAdapter);
5842 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5843
Jeff Johnsone7245742012-09-05 17:12:55 -07005844 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 return 0;
5846}
5847
5848static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5849 u8* mac, struct station_info *sinfo)
5850{
5851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5853 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5854 tANI_U8 rate_flags;
5855
5856 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5857 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5858 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5859
5860 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5861 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5862 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5863 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5864 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5865 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5866 tANI_U16 maxRate = 0;
5867 tANI_U16 myRate;
5868 tANI_U16 currentRate = 0;
5869 tANI_U8 maxSpeedMCS = 0;
5870 tANI_U8 maxMCSIdx = 0;
5871 tANI_U8 rateFlag = 1;
5872 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005873 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005874
Jeff Johnsone7245742012-09-05 17:12:55 -07005875 ENTER();
5876
Jeff Johnson295189b2012-06-20 16:38:30 -07005877 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5878 (0 == ssidlen))
5879 {
5880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5881 " Invalid ssidlen, %d", __func__, ssidlen);
5882 /*To keep GUI happy*/
5883 return 0;
5884 }
5885
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005886 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5887 {
5888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5889 "%s:LOGP in Progress. Ignore!!!", __func__);
5890 return -EAGAIN;
5891 }
5892
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5894 sinfo->filled |= STATION_INFO_SIGNAL;
5895
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005896 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5898
5899 //convert to the UI units of 100kbps
5900 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5901
5902#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005903 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 -07005904 sinfo->signal,
5905 pCfg->reportMaxLinkSpeed,
5906 myRate,
5907 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005908 (int) pCfg->linkSpeedRssiMid,
5909 (int) pCfg->linkSpeedRssiLow,
5910 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005911#endif //LINKSPEED_DEBUG_ENABLED
5912
5913 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5914 {
5915 // we do not want to necessarily report the current speed
5916 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5917 {
5918 // report the max possible speed
5919 rssidx = 0;
5920 }
5921 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5922 {
5923 // report the max possible speed with RSSI scaling
5924 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5925 {
5926 // report the max possible speed
5927 rssidx = 0;
5928 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005929 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 {
5931 // report middle speed
5932 rssidx = 1;
5933 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005934 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5935 {
5936 // report middle speed
5937 rssidx = 2;
5938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 else
5940 {
5941 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005942 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 }
5944 }
5945 else
5946 {
5947 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5948 hddLog(VOS_TRACE_LEVEL_ERROR,
5949 "%s: Invalid value for reportMaxLinkSpeed: %u",
5950 __func__, pCfg->reportMaxLinkSpeed);
5951 rssidx = 0;
5952 }
5953
5954 maxRate = 0;
5955
5956 /* Get Basic Rate Set */
5957 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5958 for (i = 0; i < ORLeng; i++)
5959 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005960 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 {
5962 /* Validate Rate Set */
5963 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5964 {
5965 currentRate = supported_data_rate[j].supported_rate[rssidx];
5966 break;
5967 }
5968 }
5969 /* Update MAX rate */
5970 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5971 }
5972
5973 /* Get Extended Rate Set */
5974 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5975 for (i = 0; i < ERLeng; i++)
5976 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005977 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 {
5979 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
5980 {
5981 currentRate = supported_data_rate[j].supported_rate[rssidx];
5982 break;
5983 }
5984 }
5985 /* Update MAX rate */
5986 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5987 }
5988
5989 /* Get MCS Rate Set -- but only if we are connected at MCS
5990 rates or if we are always reporting max speed or if we have
5991 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005992 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 {
5994 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
5995 rateFlag = 0;
5996 if (rate_flags & eHAL_TX_RATE_HT40)
5997 {
5998 rateFlag |= 1;
5999 }
6000 if (rate_flags & eHAL_TX_RATE_SGI)
6001 {
6002 rateFlag |= 2;
6003 }
6004
6005 for (i = 0; i < MCSLeng; i++)
6006 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006007 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6008 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 {
6010 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6011 {
6012 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6013 break;
6014 }
6015 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006016 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 {
6018 maxRate = currentRate;
6019 maxSpeedMCS = 1;
6020 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6021 }
6022 }
6023 }
6024
6025 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006026 if (((maxRate < myRate) && (0 == rssidx)) ||
6027 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 {
6029 maxRate = myRate;
6030 if (rate_flags & eHAL_TX_RATE_LEGACY)
6031 {
6032 maxSpeedMCS = 0;
6033 }
6034 else
6035 {
6036 maxSpeedMCS = 1;
6037 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6038 }
6039 }
6040
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006041 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 {
6043 sinfo->txrate.legacy = maxRate;
6044#ifdef LINKSPEED_DEBUG_ENABLED
6045 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6046#endif //LINKSPEED_DEBUG_ENABLED
6047 }
6048 else
6049 {
6050 sinfo->txrate.mcs = maxMCSIdx;
6051 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6052 if (rate_flags & eHAL_TX_RATE_SGI)
6053 {
6054 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6055 }
6056 if (rate_flags & eHAL_TX_RATE_HT40)
6057 {
6058 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6059 }
6060#ifdef LINKSPEED_DEBUG_ENABLED
6061 pr_info("Reporting MCS rate %d flags %x\n",
6062 sinfo->txrate.mcs,
6063 sinfo->txrate.flags );
6064#endif //LINKSPEED_DEBUG_ENABLED
6065 }
6066 }
6067 else
6068 {
6069 // report current rate instead of max rate
6070
6071 if (rate_flags & eHAL_TX_RATE_LEGACY)
6072 {
6073 //provide to the UI in units of 100kbps
6074 sinfo->txrate.legacy = myRate;
6075#ifdef LINKSPEED_DEBUG_ENABLED
6076 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6077#endif //LINKSPEED_DEBUG_ENABLED
6078 }
6079 else
6080 {
6081 //must be MCS
6082 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6083 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6084 if (rate_flags & eHAL_TX_RATE_SGI)
6085 {
6086 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6087 }
6088 if (rate_flags & eHAL_TX_RATE_HT40)
6089 {
6090 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6091 }
6092#ifdef LINKSPEED_DEBUG_ENABLED
6093 pr_info("Reporting actual MCS rate %d flags %x\n",
6094 sinfo->txrate.mcs,
6095 sinfo->txrate.flags );
6096#endif //LINKSPEED_DEBUG_ENABLED
6097 }
6098 }
6099 sinfo->filled |= STATION_INFO_TX_BITRATE;
6100
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006101 sinfo->tx_packets =
6102 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6103 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6104 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6105 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6106
6107 sinfo->tx_retries =
6108 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6109 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6110 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6111 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6112
6113 sinfo->tx_failed =
6114 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6115 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6116 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6117 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6118
6119 sinfo->filled |=
6120 STATION_INFO_TX_PACKETS |
6121 STATION_INFO_TX_RETRIES |
6122 STATION_INFO_TX_FAILED;
6123
6124 EXIT();
6125 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006126}
6127
6128static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6129 struct net_device *dev, bool mode, v_SINT_t timeout)
6130{
6131 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6132 VOS_STATUS vos_status;
6133
Jeff Johnsone7245742012-09-05 17:12:55 -07006134 ENTER();
6135
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 if (NULL == pAdapter)
6137 {
6138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6139 return -ENODEV;
6140 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006141 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6142 {
6143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6144 "%s:LOGP in Progress. Ignore!!!", __func__);
6145 return -EAGAIN;
6146 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006147
6148 /**The get power cmd from the supplicant gets updated by the nl only
6149 *on successful execution of the function call
6150 *we are oppositely mapped w.r.t mode in the driver
6151 **/
6152 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6153
Jeff Johnsone7245742012-09-05 17:12:55 -07006154 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 if (VOS_STATUS_E_FAILURE == vos_status)
6156 {
6157 return -EINVAL;
6158 }
6159 return 0;
6160}
6161
6162
6163#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6164static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6165 struct net_device *netdev,
6166 u8 key_index)
6167{
Jeff Johnsone7245742012-09-05 17:12:55 -07006168 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 return 0;
6170}
6171#endif //LINUX_VERSION_CODE
6172
6173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6174static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6175 struct net_device *dev,
6176 struct ieee80211_txq_params *params)
6177{
Jeff Johnsone7245742012-09-05 17:12:55 -07006178 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 return 0;
6180}
6181#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6182static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6183 struct ieee80211_txq_params *params)
6184{
Jeff Johnsone7245742012-09-05 17:12:55 -07006185 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 return 0;
6187}
6188#endif //LINUX_VERSION_CODE
6189
6190static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6191 struct net_device *dev, u8 *mac)
6192{
6193 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006194 VOS_STATUS vos_status;
6195 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006196
Jeff Johnsone7245742012-09-05 17:12:55 -07006197 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6199 {
6200 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6201 return -EINVAL;
6202 }
6203
6204 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6205 {
6206 hddLog( LOGE,
6207 "%s: Wlan Load/Unload is in progress", __func__);
6208 return -EBUSY;
6209 }
6210
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006211 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6212 {
6213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6214 "%s:LOGP in Progress. Ignore!!!", __func__);
6215 return -EAGAIN;
6216 }
6217
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6219#ifdef WLAN_FEATURE_P2P
6220 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6221#endif
6222 )
6223 {
6224 if( NULL == mac )
6225 {
6226 v_U16_t i;
6227 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6228 {
6229 if(pAdapter->aStaInfo[i].isUsed)
6230 {
6231 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6232 hddLog(VOS_TRACE_LEVEL_INFO,
6233 "%s: Delete STA with MAC::"
6234 "%02x:%02x:%02x:%02x:%02x:%02x",
6235 __func__,
6236 macAddr[0], macAddr[1], macAddr[2],
6237 macAddr[3], macAddr[4], macAddr[5]);
6238 hdd_softap_sta_deauth(pAdapter, macAddr);
6239 }
6240 }
6241 }
6242 else
6243 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006244
6245 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6246 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6247 {
6248 hddLog(VOS_TRACE_LEVEL_INFO,
6249 "%s: Skip this DEL STA as this is not used::"
6250 "%02x:%02x:%02x:%02x:%02x:%02x",
6251 __func__,
6252 mac[0], mac[1], mac[2],
6253 mac[3], mac[4], mac[5]);
6254 return -ENOENT;
6255 }
6256
6257 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6258 {
6259 hddLog(VOS_TRACE_LEVEL_INFO,
6260 "%s: Skip this DEL STA as deauth is in progress::"
6261 "%02x:%02x:%02x:%02x:%02x:%02x",
6262 __func__,
6263 mac[0], mac[1], mac[2],
6264 mac[3], mac[4], mac[5]);
6265 return -ENOENT;
6266 }
6267
6268 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6269
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 hddLog(VOS_TRACE_LEVEL_INFO,
6271 "%s: Delete STA with MAC::"
6272 "%02x:%02x:%02x:%02x:%02x:%02x",
6273 __func__,
6274 mac[0], mac[1], mac[2],
6275 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006276
6277 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6278 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6279 {
6280 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6281 hddLog(VOS_TRACE_LEVEL_INFO,
6282 "%s: STA removal failed for ::"
6283 "%02x:%02x:%02x:%02x:%02x:%02x",
6284 __func__,
6285 mac[0], mac[1], mac[2],
6286 mac[3], mac[4], mac[5]);
6287 return -ENOENT;
6288 }
6289
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 }
6291 }
6292
6293 EXIT();
6294
6295 return 0;
6296}
6297
6298static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6299 struct net_device *dev, u8 *mac, struct station_parameters *params)
6300{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006301#ifdef FEATURE_WLAN_TDLS
6302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6303 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6304 u32 mask, set;
6305 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006306 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006307
6308 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6309 {
6310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6311 "Invalid arguments");
6312 return -EINVAL;
6313 }
6314
6315 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6316 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6317 {
6318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6319 "TDLS Disabled in INI OR not enabled in FW.\
6320 Cannot process TDLS commands \n");
6321 return -ENOTSUPP;
6322 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006323 /* first to check if we reached to maximum supported TDLS peer.
6324 TODO: for now, return -EPERM looks working fine,
6325 but need to check if any other errno fit into this category.*/
6326 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6327 {
6328 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6329 "%s: TDLS Max peer already connected. Request declined. \n",
6330 __func__);
6331 return -EPERM;
6332 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006333
6334 mask = params->sta_flags_mask;
6335
6336 set = params->sta_flags_set;
6337
6338
Lee Hoonkic1262f22013-01-24 21:59:00 -08006339 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6340 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006341
6342 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6343 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6345 "Add TDLS peer");
6346
6347
6348 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6349 pAdapter->sessionId, mac);
6350
6351 if (VOS_STATUS_SUCCESS != status) {
6352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6353 "%s: sme_AddTdlsPeerSta failed!", __func__);
6354 }
6355 }
6356 }
6357#endif
6358
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 return 0;
6360}
6361
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006362
6363#ifdef FEATURE_WLAN_LFR
6364static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006365 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006366{
6367#define MAX_PMKSAIDS_IN_CACHE 8
6368 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006369 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006370 tANI_U32 j=0;
6371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6372 tHalHandle halHandle;
6373 eHalStatus result;
6374 tANI_U8 BSSIDMatched = 0;
6375
Jeff Johnsone7245742012-09-05 17:12:55 -07006376 ENTER();
6377
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006378 // Validate pAdapter
6379 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6380 {
6381 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6382 return -EINVAL;
6383 }
6384
6385 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6386 {
6387 hddLog( LOGE,
6388 "%s: Wlan Load/Unload is in progress", __func__);
6389 return -EBUSY;
6390 }
6391
6392 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6393 {
6394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6395 "%s:LOGP in Progress. Ignore!!!", __func__);
6396 return -EAGAIN;
6397 }
6398
6399 // Retrieve halHandle
6400 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6401
6402 for (j = 0; j < i; j++)
6403 {
6404 if(vos_mem_compare(PMKIDCache[j].BSSID,
6405 pmksa->bssid, WNI_CFG_BSSID_LEN))
6406 {
6407 /* BSSID matched previous entry. Overwrite it. */
6408 BSSIDMatched = 1;
6409 vos_mem_copy(PMKIDCache[j].BSSID,
6410 pmksa->bssid, WNI_CFG_BSSID_LEN);
6411 vos_mem_copy(PMKIDCache[j].PMKID,
6412 pmksa->pmkid,
6413 CSR_RSN_PMKID_SIZE);
6414 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006415 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006416 dump_bssid(pmksa->bssid);
6417 dump_pmkid(halHandle, pmksa->pmkid);
6418 break;
6419 }
6420 }
6421
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006422 /* Check we compared all entries,if then take the first slot now */
6423 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6424
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006425 if (!BSSIDMatched)
6426 {
6427 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6428 vos_mem_copy(PMKIDCache[i].BSSID,
6429 pmksa->bssid, ETHER_ADDR_LEN);
6430 vos_mem_copy(PMKIDCache[i].PMKID,
6431 pmksa->pmkid,
6432 CSR_RSN_PMKID_SIZE);
6433 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006434 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006435 dump_bssid(pmksa->bssid);
6436 dump_pmkid(halHandle, pmksa->pmkid);
6437 // Increment the HDD Local Cache index
6438 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6439 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6440 }
6441
6442
6443 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6444 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006445 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006446 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006447 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006448 // Finally set the PMKSA ID Cache in CSR
6449 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6450 PMKIDCache,
6451 i );
6452 return 0;
6453}
6454
6455
6456static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006457 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006458{
Jeff Johnsone7245742012-09-05 17:12:55 -07006459 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006460 // TODO: Implement this later.
6461 return 0;
6462}
6463
6464static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6465{
Jeff Johnsone7245742012-09-05 17:12:55 -07006466 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006467 // TODO: Implement this later.
6468 return 0;
6469}
6470#endif
6471
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006472#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6473static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6474 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6475{
6476 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6477 hdd_station_ctx_t *pHddStaCtx;
6478
6479 if (NULL == pAdapter)
6480 {
6481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6482 return -ENODEV;
6483 }
6484
6485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6486
6487 // Added for debug on reception of Re-assoc Req.
6488 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6489 {
6490 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6491 ftie->ie_len);
6492 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6493 }
6494
6495#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6496 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6497 ftie->ie_len);
6498#endif
6499
6500 // Pass the received FT IEs to SME
6501 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6502 ftie->ie_len);
6503 return 0;
6504}
6505#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006506
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006507#ifdef FEATURE_WLAN_TDLS
6508static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6509 u8 *peer, u8 action_code, u8 dialog_token,
6510 u16 status_code, const u8 *buf, size_t len)
6511{
6512
6513 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6514 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006515 u8 peerMac[6];
6516 VOS_STATUS status;
Hoonki Leea34dd892013-02-05 22:56:02 -08006517 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006518
6519 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6520 {
6521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6522 "Invalid arguments");
6523 return -EINVAL;
6524 }
6525
6526 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6527 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6528 {
6529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6530 "TDLS Disabled in INI OR not enabled in FW.\
6531 Cannot process TDLS commands \n");
6532 return -ENOTSUPP;
6533 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006534
6535 if(SIR_MAC_TDLS_SETUP_REQ == action_code ||
6536 SIR_MAC_TDLS_SETUP_RSP == action_code )
6537 {
6538 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6539 {
6540 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6541 we return error code at 'add_station()'. Hence we have this
6542 check again in addtion to add_station().
6543 Anyway, there is no hard to double-check. */
6544 if(SIR_MAC_TDLS_SETUP_REQ == action_code)
6545 {
6546 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6547 "%s: TDLS Max peer already connected. Request declined. \n",
6548 __func__);
6549 return -EPERM;
6550 }
6551 else
6552 {
6553 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6554 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6555 "%s: TDLS Max peer already connected send response status %d \n",
6556 __func__,status_code);
6557 }
6558 }
6559 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006560 vos_mem_copy( peerMac, peer, 6);
6561
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006562#ifdef WLAN_FEATURE_TDLS_DEBUG
6563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6564 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6565 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6566 action_code, dialog_token, status_code, len);
6567#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006568
Hoonki Leea34dd892013-02-05 22:56:02 -08006569 /*Except teardown responder will not be used so just make 0*/
6570 responder = 0;
6571 if(SIR_MAC_TDLS_TEARDOWN == action_code)
6572 {
6573 responder = wlan_hdd_tdls_get_responder(peerMac);
6574 if(-1 == responder)
6575 {
6576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6577 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6578 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6579 dialog_token, status_code, len);
6580 return -EPERM;
6581 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006582 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006583
6584 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006585 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006586
6587 if (VOS_STATUS_SUCCESS != status) {
6588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6589 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6590 }
6591
Hoonki Leea34dd892013-02-05 22:56:02 -08006592 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6593 {
6594 wlan_hdd_tdls_set_responder(peerMac, TRUE);
6595 }
6596 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6597 {
6598 wlan_hdd_tdls_set_responder(peerMac, FALSE);
6599 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006600
6601 return 0;
6602}
6603
6604static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6605 u8 *peer, enum nl80211_tdls_operation oper)
6606{
6607 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6608 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006609#ifdef WLAN_FEATURE_TDLS_DEBUG
6610 const char *tdls_oper_str[]= {
6611 "NL80211_TDLS_DISCOVERY_REQ",
6612 "NL80211_TDLS_SETUP",
6613 "NL80211_TDLS_TEARDOWN",
6614 "NL80211_TDLS_ENABLE_LINK",
6615 "NL80211_TDLS_DISABLE_LINK",
6616 "NL80211_TDLS_UNKONW_OPER"};
6617#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006618
6619 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6620 {
6621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6622 "Invalid arguments");
6623 return -EINVAL;
6624 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006625
6626#ifdef WLAN_FEATURE_TDLS_DEBUG
6627 if((int)oper > 4)
6628 oper = 5;
6629
6630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6631 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6632 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6633 tdls_oper_str[(int)oper]);
6634#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006635
6636 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006637 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006638 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006640 "TDLS Disabled in INI OR not enabled in FW.\
6641 Cannot process TDLS commands \n");
6642 return -ENOTSUPP;
6643 }
6644
6645 switch (oper) {
6646 case NL80211_TDLS_ENABLE_LINK:
6647 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006648 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Hoonki Lee387663d2013-02-05 18:08:43 -08006649 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006650 VOS_STATUS status;
6651
6652 if (peer) {
Hoonki Lee387663d2013-02-05 18:08:43 -08006653 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006654
6655 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006656 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006657 __func__, peer[0], peer[1],
6658 peer[2], peer[3],
6659 peer[4], peer[5] );
6660
Hoonki Lee387663d2013-02-05 18:08:43 -08006661 if ( NULL == pTdlsPeer ) {
6662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6663 __func__, peer[0], peer[1],
6664 peer[2], peer[3],
6665 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006666 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006667 }
6668
Hoonki Lee387663d2013-02-05 18:08:43 -08006669 status = WLANTL_ChangeSTAState( pVosContext, pTdlsPeer->staId,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006670 WLANTL_STA_AUTHENTICATED );
6671
Hoonki Leef63df0d2013-01-16 19:29:14 -08006672 //This can fail only if the staId is not registered yet with TL
6673 //return -EINVAL in such case.
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006674 if (0 != status) {
6675 hddLog(VOS_TRACE_LEVEL_ERROR,
6676 "%s: WLANTL_ChangeSTAState failed, returned %d",
6677 __func__, status);
Hoonki Leef63df0d2013-01-16 19:29:14 -08006678 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006679 }
Hoonki Leef63df0d2013-01-16 19:29:14 -08006680
Hoonki Lee387663d2013-02-05 18:08:43 -08006681 wlan_hdd_tdls_set_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Chilam NG571c65a2013-01-19 12:27:36 +05306682
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006683 } else {
6684 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6685 }
6686 }
6687 break;
6688 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006689 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006690 if(NULL != wlan_hdd_tdls_find_peer(peer))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006691 {
6692 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6693 pAdapter->sessionId, peer );
6694 }
6695 else
6696 {
6697 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6698 "%s: TDLS Peer Station doesn't exist \n",__func__);
6699 }
6700 return 0;
6701 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006702 case NL80211_TDLS_TEARDOWN:
6703 case NL80211_TDLS_SETUP:
6704 case NL80211_TDLS_DISCOVERY_REQ:
6705 /* We don't support in-driver setup/teardown/discovery */
6706 return -ENOTSUPP;
6707 default:
6708 return -ENOTSUPP;
6709 }
6710 return 0;
6711}
Chilam NG571c65a2013-01-19 12:27:36 +05306712
6713int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6714 struct net_device *dev, u8 *peer)
6715{
6716 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6717 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6718
6719 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6720 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6721}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006722#endif
6723
Jeff Johnson295189b2012-06-20 16:38:30 -07006724/* cfg80211_ops */
6725static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6726{
6727 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6728 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6729 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6730 .change_station = wlan_hdd_change_station,
6731#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6732 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6733 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6734 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006735#else
6736 .start_ap = wlan_hdd_cfg80211_start_ap,
6737 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6738 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006739#endif
6740 .change_bss = wlan_hdd_cfg80211_change_bss,
6741 .add_key = wlan_hdd_cfg80211_add_key,
6742 .get_key = wlan_hdd_cfg80211_get_key,
6743 .del_key = wlan_hdd_cfg80211_del_key,
6744 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006745#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006747#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 .scan = wlan_hdd_cfg80211_scan,
6749 .connect = wlan_hdd_cfg80211_connect,
6750 .disconnect = wlan_hdd_cfg80211_disconnect,
6751 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6752 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6753 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6754 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6755 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6756#ifdef WLAN_FEATURE_P2P
6757 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6758 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6759 .mgmt_tx = wlan_hdd_action,
6760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6761 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6762 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6763 .set_txq_params = wlan_hdd_set_txq_params,
6764#endif
6765#endif
6766 .get_station = wlan_hdd_cfg80211_get_station,
6767 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6768 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006769 .add_station = wlan_hdd_cfg80211_add_station,
6770#ifdef FEATURE_WLAN_LFR
6771 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6772 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6773 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6774#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006775#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6776 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6777#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006778#ifdef FEATURE_WLAN_TDLS
6779 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6780 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6781#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006782};
6783
6784#endif // CONFIG_CFG80211