blob: cfbbede018fd1be9f147bde0f25554e850f041b2 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala9c070ad2013-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 Khannac0b992f2012-12-04 15:08:18 -0800104#ifdef FEATURE_WLAN_TDLS
105#include "wlan_hdd_tdls.h"
106#endif
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +0530107#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define g_mode_rates_size (12)
110#define a_mode_rates_size (8)
111#define FREQ_BASE_80211G (2407)
112#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700113#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
115 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
116
117#define HDD2GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_2GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD5GHZCHAN(freq, chan, flag) { \
127 .band = IEEE80211_BAND_5GHZ, \
128 .center_freq = (freq), \
129 .hw_value = (chan),\
130 .flags = (flag), \
131 .max_antenna_gain = 0 ,\
132 .max_power = 30, \
133}
134
135#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
136{\
137 .bitrate = rate, \
138 .hw_value = rate_id, \
139 .flags = flag, \
140}
141
Lee Hoonkif1431702013-01-24 21:59:00 -0800142#ifndef WLAN_FEATURE_TDLS_DEBUG
143#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
144#else
145#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
146#endif
147
Jeff Johnson295189b2012-06-20 16:38:30 -0700148static const u32 hdd_cipher_suites[] =
149{
150 WLAN_CIPHER_SUITE_WEP40,
151 WLAN_CIPHER_SUITE_WEP104,
152 WLAN_CIPHER_SUITE_TKIP,
153#ifdef FEATURE_WLAN_CCX
154#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
155 WLAN_CIPHER_SUITE_KRK,
156 WLAN_CIPHER_SUITE_CCMP,
157#else
158 WLAN_CIPHER_SUITE_CCMP,
159#endif
160#ifdef FEATURE_WLAN_WAPI
161 WLAN_CIPHER_SUITE_SMS4,
162#endif
163};
164
165static inline int is_broadcast_ether_addr(const u8 *addr)
166{
167 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
168 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
169}
170
171static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
172{
173 HDD2GHZCHAN(2412, 1, 0) ,
174 HDD2GHZCHAN(2417, 2, 0) ,
175 HDD2GHZCHAN(2422, 3, 0) ,
176 HDD2GHZCHAN(2427, 4, 0) ,
177 HDD2GHZCHAN(2432, 5, 0) ,
178 HDD2GHZCHAN(2437, 6, 0) ,
179 HDD2GHZCHAN(2442, 7, 0) ,
180 HDD2GHZCHAN(2447, 8, 0) ,
181 HDD2GHZCHAN(2452, 9, 0) ,
182 HDD2GHZCHAN(2457, 10, 0) ,
183 HDD2GHZCHAN(2462, 11, 0) ,
184 HDD2GHZCHAN(2467, 12, 0) ,
185 HDD2GHZCHAN(2472, 13, 0) ,
186 HDD2GHZCHAN(2484, 14, 0) ,
187};
188
189#ifdef WLAN_FEATURE_P2P
190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
196#endif
197
198static struct ieee80211_channel hdd_channels_5_GHZ[] =
199{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700200 HDD5GHZCHAN(4920, 240, 0) ,
201 HDD5GHZCHAN(4940, 244, 0) ,
202 HDD5GHZCHAN(4960, 248, 0) ,
203 HDD5GHZCHAN(4980, 252, 0) ,
204 HDD5GHZCHAN(5040, 208, 0) ,
205 HDD5GHZCHAN(5060, 212, 0) ,
206 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 HDD5GHZCHAN(5180, 36, 0) ,
208 HDD5GHZCHAN(5200, 40, 0) ,
209 HDD5GHZCHAN(5220, 44, 0) ,
210 HDD5GHZCHAN(5240, 48, 0) ,
211 HDD5GHZCHAN(5260, 52, 0) ,
212 HDD5GHZCHAN(5280, 56, 0) ,
213 HDD5GHZCHAN(5300, 60, 0) ,
214 HDD5GHZCHAN(5320, 64, 0) ,
215 HDD5GHZCHAN(5500,100, 0) ,
216 HDD5GHZCHAN(5520,104, 0) ,
217 HDD5GHZCHAN(5540,108, 0) ,
218 HDD5GHZCHAN(5560,112, 0) ,
219 HDD5GHZCHAN(5580,116, 0) ,
220 HDD5GHZCHAN(5600,120, 0) ,
221 HDD5GHZCHAN(5620,124, 0) ,
222 HDD5GHZCHAN(5640,128, 0) ,
223 HDD5GHZCHAN(5660,132, 0) ,
224 HDD5GHZCHAN(5680,136, 0) ,
225 HDD5GHZCHAN(5700,140, 0) ,
226 HDD5GHZCHAN(5745,149, 0) ,
227 HDD5GHZCHAN(5765,153, 0) ,
228 HDD5GHZCHAN(5785,157, 0) ,
229 HDD5GHZCHAN(5805,161, 0) ,
230 HDD5GHZCHAN(5825,165, 0) ,
231};
232
233static struct ieee80211_rate g_mode_rates[] =
234{
235 HDD_G_MODE_RATETAB(10, 0x1, 0),
236 HDD_G_MODE_RATETAB(20, 0x2, 0),
237 HDD_G_MODE_RATETAB(55, 0x4, 0),
238 HDD_G_MODE_RATETAB(110, 0x8, 0),
239 HDD_G_MODE_RATETAB(60, 0x10, 0),
240 HDD_G_MODE_RATETAB(90, 0x20, 0),
241 HDD_G_MODE_RATETAB(120, 0x40, 0),
242 HDD_G_MODE_RATETAB(180, 0x80, 0),
243 HDD_G_MODE_RATETAB(240, 0x100, 0),
244 HDD_G_MODE_RATETAB(360, 0x200, 0),
245 HDD_G_MODE_RATETAB(480, 0x400, 0),
246 HDD_G_MODE_RATETAB(540, 0x800, 0),
247};
248
249static struct ieee80211_rate a_mode_rates[] =
250{
251 HDD_G_MODE_RATETAB(60, 0x10, 0),
252 HDD_G_MODE_RATETAB(90, 0x20, 0),
253 HDD_G_MODE_RATETAB(120, 0x40, 0),
254 HDD_G_MODE_RATETAB(180, 0x80, 0),
255 HDD_G_MODE_RATETAB(240, 0x100, 0),
256 HDD_G_MODE_RATETAB(360, 0x200, 0),
257 HDD_G_MODE_RATETAB(480, 0x400, 0),
258 HDD_G_MODE_RATETAB(540, 0x800, 0),
259};
260
261static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
262{
263 .channels = hdd_channels_2_4_GHZ,
264 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
265 .band = IEEE80211_BAND_2GHZ,
266 .bitrates = g_mode_rates,
267 .n_bitrates = g_mode_rates_size,
268 .ht_cap.ht_supported = 1,
269 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
270 | IEEE80211_HT_CAP_GRN_FLD
271 | IEEE80211_HT_CAP_DSSSCCK40
272 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
273 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
274 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
275 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
276 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
277 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
278};
279
280#ifdef WLAN_FEATURE_P2P
281static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
282{
283 .channels = hdd_social_channels_2_4_GHZ,
284 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
285 .band = IEEE80211_BAND_2GHZ,
286 .bitrates = g_mode_rates,
287 .n_bitrates = g_mode_rates_size,
288 .ht_cap.ht_supported = 1,
289 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
290 | IEEE80211_HT_CAP_GRN_FLD
291 | IEEE80211_HT_CAP_DSSSCCK40
292 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
293 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
294 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
295 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
296 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
297 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
298};
299#endif
300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
322/* This structure contain information what kind of frame are expected in
323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
341#ifdef WLAN_FEATURE_P2P
342 [NL80211_IFTYPE_P2P_CLIENT] = {
343 .tx = 0xffff,
344 .rx = BIT(SIR_MAC_MGMT_ACTION) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ),
346 },
347 [NL80211_IFTYPE_P2P_GO] = {
348 /* This is also same as for SoftAP */
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
351 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
352 BIT(SIR_MAC_MGMT_PROBE_REQ) |
353 BIT(SIR_MAC_MGMT_DISASSOC) |
354 BIT(SIR_MAC_MGMT_AUTH) |
355 BIT(SIR_MAC_MGMT_DEAUTH) |
356 BIT(SIR_MAC_MGMT_ACTION),
357 },
Jeff Johnsoncab8ddc2013-01-18 17:05:29 -0800358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700359};
360
Sudhir Sattayappa Kohalli0c7606f2013-01-16 17:35:13 -0800361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
362#ifdef WLAN_FEATURE_P2P
363static const struct ieee80211_iface_limit
364wlan_hdd_iface_limit[] = {
365 {
Sunil Ravice1c00c2013-01-31 06:12:22 -0800366 /* max = 3 ; Our driver create two interfaces during driver init
367 * wlan0 and p2p0 interfaces. p2p0 is considered as station
368 * interface until a group is formed. In JB architecture, once the
369 * group is formed, interface type of p2p0 is changed to P2P GO or
370 * Client.
371 * When supplicant remove the group, it first issue a set interface
372 * cmd to change the mode back to Station. In JB this works fine as
373 * we advertize two station type interface during driver init.
374 * Some vendors create separate interface for P2P GO/Client,
375 * after group formation(Third one). But while group remove
376 * supplicant first tries to change the mode(3rd interface) to STATION
377 * But as we advertized only two sta type interfaces nl80211 was
378 * returning error for the third one which was leading to failure in
379 * delete interface. Ideally while removing the group, supplicant
380 * should not try to change the 3rd interface mode to Station type.
381 * Till we get a fix in wpa_supplicant, we advertize max STA
382 * interface type to 3
383 */
384 .max = 3,
Sudhir Sattayappa Kohalli0c7606f2013-01-16 17:35:13 -0800385 .types = BIT(NL80211_IFTYPE_STATION),
386 },
387 {
388 .max = 1,
389 .types = BIT(NL80211_IFTYPE_AP),
390 },
391 {
392 .max = 1,
393 .types = BIT(NL80211_IFTYPE_P2P_GO) |
394 BIT(NL80211_IFTYPE_P2P_CLIENT),
395 },
396};
397
398/* By default, only single channel concurrency is allowed */
399static struct ieee80211_iface_combination
400wlan_hdd_iface_combination = {
401 .limits = wlan_hdd_iface_limit,
402 .num_different_channels = 1,
Sunil Ravice1c00c2013-01-31 06:12:22 -0800403 /*
404 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
405 * and p2p0 interfaces during driver init
406 * Some vendors create separate interface for P2P operations.
407 * wlan0: STA interface
408 * p2p0: P2P Device interface, action frames goes
409 * through this interface.
410 * p2p-xx: P2P interface, After GO negotiation this interface is
411 * created for p2p operations(GO/CLIENT interface).
412 */
413 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli0c7606f2013-01-16 17:35:13 -0800414 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
415 .beacon_int_infra_match = false,
416};
417#endif
418#endif
419
Jeff Johnson295189b2012-06-20 16:38:30 -0700420static struct cfg80211_ops wlan_hdd_cfg80211_ops;
421
422/* Data rate 100KBPS based on IE Index */
423struct index_data_rate_type
424{
425 v_U8_t beacon_rate_index;
426 v_U16_t supported_rate[4];
427};
428
429/* 11B, 11G Rate table include Basic rate and Extended rate
430 The IDX field is the rate index
431 The HI field is the rate when RSSI is strong or being ignored
432 (in this case we report actual rate)
433 The MID field is the rate when RSSI is moderate
434 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
435 The LO field is the rate when RSSI is low
436 (in this case we don't report rates, actual current rate used)
437 */
438static const struct
439{
440 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700441 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700442} supported_data_rate[] =
443{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700444/* IDX HI HM LM LO (RSSI-based index */
445 {2, { 10, 10, 10, 0}},
446 {4, { 20, 20, 10, 0}},
447 {11, { 55, 20, 10, 0}},
448 {12, { 60, 55, 20, 0}},
449 {18, { 90, 55, 20, 0}},
450 {22, {110, 55, 20, 0}},
451 {24, {120, 90, 60, 0}},
452 {36, {180, 120, 60, 0}},
453 {44, {220, 180, 60, 0}},
454 {48, {240, 180, 90, 0}},
455 {66, {330, 180, 90, 0}},
456 {72, {360, 240, 90, 0}},
457 {96, {480, 240, 120, 0}},
458 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700459};
460
461/* MCS Based rate table */
462static struct index_data_rate_type supported_mcs_rate[] =
463{
464/* MCS L20 L40 S20 S40 */
465 {0, {65, 135, 72, 150}},
466 {1, {130, 270, 144, 300}},
467 {2, {195, 405, 217, 450}},
468 {3, {260, 540, 289, 600}},
469 {4, {390, 810, 433, 900}},
470 {5, {520, 1080, 578, 1200}},
471 {6, {585, 1215, 650, 1350}},
472 {7, {650, 1350, 722, 1500}}
473};
474
475extern struct net_device_ops net_ops_struct;
476
477/*
478 * FUNCTION: wlan_hdd_cfg80211_init
479 * This function is called by hdd_wlan_startup()
480 * during initialization.
481 * This function is used to initialize and register wiphy structure.
482 */
483struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
484{
485 struct wiphy *wiphy;
486 ENTER();
487
488 /*
489 * Create wiphy device
490 */
491 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
492
493 if (!wiphy)
494 {
495 /* Print error and jump into err label and free the memory */
496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
497 return NULL;
498 }
499
500 return wiphy;
501}
502
503/*
504 * FUNCTION: wlan_hdd_cfg80211_update_band
505 * This function is called from the supplicant through a
506 * private ioctl to change the band value
507 */
508int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
509{
Jeff Johnsone7245742012-09-05 17:12:55 -0700510 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700511 switch(eBand)
512 {
513 case eCSR_BAND_24:
514 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
515 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
516 break;
517 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700518#ifdef WLAN_FEATURE_P2P
519 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
520#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700521 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700523 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
524 break;
525 case eCSR_BAND_ALL:
526 default:
527 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
528 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
529 }
530 return 0;
531}
532/*
533 * FUNCTION: wlan_hdd_cfg80211_init
534 * This function is called by hdd_wlan_startup()
535 * during initialization.
536 * This function is used to initialize and register wiphy structure.
537 */
538int wlan_hdd_cfg80211_register(struct device *dev,
539 struct wiphy *wiphy,
540 hdd_config_t *pCfg
541 )
542{
Jeff Johnsone7245742012-09-05 17:12:55 -0700543 ENTER();
544
Jeff Johnson295189b2012-06-20 16:38:30 -0700545 /* Now bind the underlying wlan device with wiphy */
546 set_wiphy_dev(wiphy, dev);
547
548 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
549
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700550 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700553 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
554 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
555 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700556 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700557#endif
James Zmuda1b617722013-01-29 08:00:17 -0800558#ifdef FEATURE_WLAN_LFR
559 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
560#endif
Mohit Khannac0b992f2012-12-04 15:08:18 -0800561#ifdef FEATURE_WLAN_TDLS
562 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
563 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
564#endif
565
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700566 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
567 driver can still register regulatory callback and
568 it will get CRDA setting in wiphy->band[], but
569 driver need to determine what to do with both
570 regulatory settings */
571 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700572
Jeff Johnson295189b2012-06-20 16:38:30 -0700573 wiphy->max_scan_ssids = MAX_SCAN_SSID;
574
575 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
576
577 /* Supports STATION & AD-HOC modes right now */
578 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
579 | BIT(NL80211_IFTYPE_ADHOC)
580#ifdef WLAN_FEATURE_P2P
581 | BIT(NL80211_IFTYPE_P2P_CLIENT)
582 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnsoncab8ddc2013-01-18 17:05:29 -0800583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700584 | BIT(NL80211_IFTYPE_AP);
585
Sudhir Sattayappa Kohalli0c7606f2013-01-16 17:35:13 -0800586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
587#ifdef WLAN_FEATURE_P2P
588 if( pCfg->enableMCC )
589 {
590 /* Currently, supports up to two channels */
591 wlan_hdd_iface_combination.num_different_channels = 2;
592
593 if( !pCfg->allowMCCGODiffBI )
594 wlan_hdd_iface_combination.beacon_int_infra_match = true;
595
596 }
597 wiphy->iface_combinations = &wlan_hdd_iface_combination;
598 wiphy->n_iface_combinations = 1;
599#endif
600#endif
601
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 /* Before registering we need to update the ht capabilitied based
603 * on ini values*/
604 if( !pCfg->ShortGI20MhzEnable )
605 {
606 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
607 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
608 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
609 }
610
611 if( !pCfg->ShortGI40MhzEnable )
612 {
613 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
614 }
615
616 if( !pCfg->nChannelBondingMode5GHz )
617 {
618 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
619 }
620
621 /*Initialize band capability*/
622 switch(pCfg->nBandCapability)
623 {
624 case eCSR_BAND_24:
625 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
626 break;
627 case eCSR_BAND_5G:
628#ifdef WLAN_FEATURE_P2P
629 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
630#endif
631 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
632 break;
633 case eCSR_BAND_ALL:
634 default:
635 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
636 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
637 }
638 /*Initialise the supported cipher suite details*/
639 wiphy->cipher_suites = hdd_cipher_suites;
640 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
641
642 /*signal strength in mBm (100*dBm) */
643 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
644
645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
646#ifdef WLAN_FEATURE_P2P
647 wiphy->max_remain_on_channel_duration = 1000;
648#endif
649#endif
650
651 /* Register our wiphy dev with cfg80211 */
652 if (0 > wiphy_register(wiphy))
653 {
654 /* print eror */
655 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
656 return -EIO;
657 }
658
659 EXIT();
660 return 0;
661}
662
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700663/* In this function we will try to get default country code from crda.
664 If the gCrdaDefaultCountryCode is configured in ini file,
665 we will try to call user space crda to get the regulatory settings for
666 that country. We will timeout if we can't get it from crda.
667 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
668*/
669int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
670{
671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
672 if (memcmp(pCfg->crdaDefaultCountryCode,
673 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
674 {
675 init_completion(&pHddCtx->driver_crda_req);
676 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
677 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
678 CRDA_WAIT_TIME);
679 }
680 return 0;
681}
682
Jeff Johnson295189b2012-06-20 16:38:30 -0700683/* In this function we will do all post VOS start initialization.
684 In this function we will register for all frame in which supplicant
685 is interested.
686*/
687void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
688{
689#ifdef WLAN_FEATURE_P2P
690 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
691 /* Register for all P2P action, public action etc frames */
692 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
693
Jeff Johnsone7245742012-09-05 17:12:55 -0700694 ENTER();
695
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 /* Right now we are registering these frame when driver is getting
697 initialized. Once we will move to 2.6.37 kernel, in which we have
698 frame register ops, we will move this code as a part of that */
699 /* GAS Initial Request */
700 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
701 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
702
703 /* GAS Initial Response */
704 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
705 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
706
707 /* GAS Comeback Request */
708 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
709 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
710
711 /* GAS Comeback Response */
712 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
713 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
714
715 /* P2P Public Action */
716 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
717 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
718 P2P_PUBLIC_ACTION_FRAME_SIZE );
719
720 /* P2P Action */
721 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
722 (v_U8_t*)P2P_ACTION_FRAME,
723 P2P_ACTION_FRAME_SIZE );
724#endif /* WLAN_FEATURE_P2P */
725}
726
727void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
728{
729#ifdef WLAN_FEATURE_P2P
730 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
731 /* Register for all P2P action, public action etc frames */
732 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
733
Jeff Johnsone7245742012-09-05 17:12:55 -0700734 ENTER();
735
Jeff Johnson295189b2012-06-20 16:38:30 -0700736 /* Right now we are registering these frame when driver is getting
737 initialized. Once we will move to 2.6.37 kernel, in which we have
738 frame register ops, we will move this code as a part of that */
739 /* GAS Initial Request */
740
741 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
742 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
743
744 /* GAS Initial Response */
745 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
746 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
747
748 /* GAS Comeback Request */
749 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
750 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
751
752 /* GAS Comeback Response */
753 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
754 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
755
756 /* P2P Public Action */
757 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
758 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
759 P2P_PUBLIC_ACTION_FRAME_SIZE );
760
761 /* P2P Action */
762 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
763 (v_U8_t*)P2P_ACTION_FRAME,
764 P2P_ACTION_FRAME_SIZE );
765#endif /* WLAN_FEATURE_P2P */
766}
767
768#ifdef FEATURE_WLAN_WAPI
769void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
770 const u8 *mac_addr, u8 *key , int key_Len)
771{
772 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
773 tCsrRoamSetKey setKey;
774 v_BOOL_t isConnected = TRUE;
775 int status = 0;
776 v_U32_t roamId= 0xFF;
777 tANI_U8 *pKeyPtr = NULL;
778 int n = 0;
779
780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
781 __func__,pAdapter->device_mode);
782
783 setKey.keyId = key_index; // Store Key ID
784 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
785 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
786 setKey.paeRole = 0 ; // the PAE role
787 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
788 {
789 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
790 }
791 else
792 {
793 isConnected = hdd_connIsConnected(pHddStaCtx);
794 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
795 }
796 setKey.keyLength = key_Len;
797 pKeyPtr = setKey.Key;
798 memcpy( pKeyPtr, key, key_Len);
799
800 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
801 __func__, key_Len);
802 for (n = 0 ; n < key_Len; n++)
803 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
804 __func__,n,setKey.Key[n]);
805
806 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
807 if ( isConnected )
808 {
809 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
810 pAdapter->sessionId, &setKey, &roamId );
811 }
812 if ( status != 0 )
813 {
814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
815 "[%4d] sme_RoamSetKey returned ERROR status= %d",
816 __LINE__, status );
817 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
818 }
819}
820#endif /* FEATURE_WLAN_WAPI*/
821
822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
823int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
824 beacon_data_t **ppBeacon,
825 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700826#else
827int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
828 beacon_data_t **ppBeacon,
829 struct cfg80211_beacon_data *params,
830 int dtim_period)
831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700832{
833 int size;
834 beacon_data_t *beacon = NULL;
835 beacon_data_t *old = NULL;
836 int head_len,tail_len;
837
Jeff Johnsone7245742012-09-05 17:12:55 -0700838 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 if (params->head && !params->head_len)
840 return -EINVAL;
841
842 old = pAdapter->sessionCtx.ap.beacon;
843
844 if (!params->head && !old)
845 return -EINVAL;
846
847 if (params->tail && !params->tail_len)
848 return -EINVAL;
849
850#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
851 /* Kernel 3.0 is not updating dtim_period for set beacon */
852 if (!params->dtim_period)
853 return -EINVAL;
854#endif
855
856 if(params->head)
857 head_len = params->head_len;
858 else
859 head_len = old->head_len;
860
861 if(params->tail || !old)
862 tail_len = params->tail_len;
863 else
864 tail_len = old->tail_len;
865
866 size = sizeof(beacon_data_t) + head_len + tail_len;
867
868 beacon = kzalloc(size, GFP_KERNEL);
869
870 if( beacon == NULL )
871 return -ENOMEM;
872
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700873#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 if(params->dtim_period || !old )
875 beacon->dtim_period = params->dtim_period;
876 else
877 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700878#else
879 if(dtim_period || !old )
880 beacon->dtim_period = dtim_period;
881 else
882 beacon->dtim_period = old->dtim_period;
883#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700884
885 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
886 beacon->tail = beacon->head + head_len;
887 beacon->head_len = head_len;
888 beacon->tail_len = tail_len;
889
890 if(params->head) {
891 memcpy (beacon->head,params->head,beacon->head_len);
892 }
893 else {
894 if(old)
895 memcpy (beacon->head,old->head,beacon->head_len);
896 }
897
898 if(params->tail) {
899 memcpy (beacon->tail,params->tail,beacon->tail_len);
900 }
901 else {
902 if(old)
903 memcpy (beacon->tail,old->tail,beacon->tail_len);
904 }
905
906 *ppBeacon = beacon;
907
908 kfree(old);
909
910 return 0;
911
912}
Jeff Johnson295189b2012-06-20 16:38:30 -0700913
914v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
915{
916 int left = length;
917 v_U8_t *ptr = pIes;
918 v_U8_t elem_id,elem_len;
919
920 while(left >= 2)
921 {
922 elem_id = ptr[0];
923 elem_len = ptr[1];
924 left -= 2;
925 if(elem_len > left)
926 {
927 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700928 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 eid,elem_len,left);
930 return NULL;
931 }
932 if (elem_id == eid)
933 {
934 return ptr;
935 }
936
937 left -= elem_len;
938 ptr += (elem_len + 2);
939 }
940 return NULL;
941}
942
Jeff Johnson295189b2012-06-20 16:38:30 -0700943/* Check if rate is 11g rate or not */
944static int wlan_hdd_rate_is_11g(u8 rate)
945{
946 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
947 u8 i;
948 for (i = 0; i < 8; i++)
949 {
950 if(rate == gRateArray[i])
951 return TRUE;
952 }
953 return FALSE;
954}
955
956/* Check for 11g rate and set proper 11g only mode */
957static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
958 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
959{
960 u8 i, num_rates = pIe[0];
961
962 pIe += 1;
963 for ( i = 0; i < num_rates; i++)
964 {
965 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
966 {
967 /* If rate set have 11g rate than change the mode to 11G */
968 *pSapHw_mode = eSAP_DOT11_MODE_11g;
969 if (pIe[i] & BASIC_RATE_MASK)
970 {
971 /* If we have 11g rate as basic rate, it means mode
972 is 11g only mode.
973 */
974 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
975 *pCheckRatesfor11g = FALSE;
976 }
977 }
978 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
979 {
980 *require_ht = TRUE;
981 }
982 }
983 return;
984}
985
986static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
987{
988 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
989 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
990 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
991 u8 checkRatesfor11g = TRUE;
992 u8 require_ht = FALSE;
993 u8 *pIe=NULL;
994
995 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
996
997 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
998 pBeacon->head_len, WLAN_EID_SUPP_RATES);
999 if (pIe != NULL)
1000 {
1001 pIe += 1;
1002 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1003 &pConfig->SapHw_mode);
1004 }
1005
1006 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1007 WLAN_EID_EXT_SUPP_RATES);
1008 if (pIe != NULL)
1009 {
1010
1011 pIe += 1;
1012 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1013 &pConfig->SapHw_mode);
1014 }
1015
1016 if( pConfig->channel > 14 )
1017 {
1018 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1019 }
1020
1021 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1022 WLAN_EID_HT_CAPABILITY);
1023
1024 if(pIe)
1025 {
1026 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1027 if(require_ht)
1028 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1029 }
1030}
1031
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001032#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001033static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1034 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001035#else
1036static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1037 struct cfg80211_beacon_data *params)
1038#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001039{
1040 v_U8_t *genie;
1041 v_U8_t total_ielen = 0, ielen = 0;
1042 v_U8_t *pIe = NULL;
1043 v_U8_t addIE[1] = {0};
1044 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -07001045 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001046
1047 genie = vos_mem_malloc(MAX_GENIE_LEN);
1048
1049 if(genie == NULL) {
1050
1051 return -ENOMEM;
1052 }
1053
1054 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1055
1056 if(pIe)
1057 {
1058 /*Copy the wps IE*/
1059 ielen = pIe[1] + 2;
1060 if( ielen <=MAX_GENIE_LEN)
1061 {
1062 vos_mem_copy(genie, pIe, ielen);
1063 }
1064 else
1065 {
1066 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001067 ret = -EINVAL;
1068 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001069 }
1070 total_ielen = ielen;
1071 }
1072
1073#ifdef WLAN_FEATURE_WFD
1074 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1075
1076 if(pIe)
1077 {
1078 ielen = pIe[1] + 2;
1079 if(total_ielen + ielen <= MAX_GENIE_LEN) {
1080 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
1081 }
1082 else {
1083 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001084 ret = -EINVAL;
1085 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 }
1087 total_ielen += ielen;
1088 }
1089#endif
1090
1091#ifdef WLAN_FEATURE_P2P
1092 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1093
1094 if(pIe)
1095 {
1096 ielen = pIe[1] + 2;
1097 if(total_ielen + ielen <= MAX_GENIE_LEN)
1098 {
1099 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
1100 }
1101 else
1102 {
1103 hddLog( VOS_TRACE_LEVEL_ERROR,
1104 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001105 ret = -EINVAL;
1106 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 }
1108 total_ielen += ielen;
1109 }
1110#endif
1111
1112 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1113 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1114 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1115 {
1116 hddLog(LOGE,
1117 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001118 ret = -EINVAL;
1119 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 }
1121
1122 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1123 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1124 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1125 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1126 ==eHAL_STATUS_FAILURE)
1127 {
1128 hddLog(LOGE,
1129 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001130 ret = -EINVAL;
1131 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 }
1133
1134 // Added for ProResp IE
1135 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1136 {
1137 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1138 u8 probe_rsp_ie_len[3] = {0};
1139 u8 counter = 0;
1140 /* Check Probe Resp Length if it is greater then 255 then Store
1141 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1142 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1143 Store More then 255 bytes into One Variable.
1144 */
1145 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1146 {
1147 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1148 {
1149 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1150 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1151 }
1152 else
1153 {
1154 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1155 rem_probe_resp_ie_len = 0;
1156 }
1157 }
1158
1159 rem_probe_resp_ie_len = 0;
1160
1161 if (probe_rsp_ie_len[0] > 0)
1162 {
1163 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1164 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1165 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1166 probe_rsp_ie_len[0], NULL,
1167 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1168 {
1169 hddLog(LOGE,
1170 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001171 ret = -EINVAL;
1172 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 }
1174 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1175 }
1176
1177 if (probe_rsp_ie_len[1] > 0)
1178 {
1179 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1180 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1181 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1182 probe_rsp_ie_len[1], NULL,
1183 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1184 {
1185 hddLog(LOGE,
1186 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001187 ret = -EINVAL;
1188 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001189 }
1190 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1191 }
1192
1193 if (probe_rsp_ie_len[2] > 0)
1194 {
1195 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1196 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1197 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1198 probe_rsp_ie_len[2], NULL,
1199 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1200 {
1201 hddLog(LOGE,
1202 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001203 ret = -EINVAL;
1204 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001205 }
1206 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1207 }
1208
1209 if (probe_rsp_ie_len[1] == 0 )
1210 {
1211 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1212 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1213 eANI_BOOLEAN_FALSE) )
1214 {
1215 hddLog(LOGE,
1216 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1217 }
1218 }
1219
1220 if (probe_rsp_ie_len[2] == 0 )
1221 {
1222 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1223 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1224 eANI_BOOLEAN_FALSE) )
1225 {
1226 hddLog(LOGE,
1227 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1228 }
1229 }
1230
1231 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1232 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1233 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1234 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1235 == eHAL_STATUS_FAILURE)
1236 {
1237 hddLog(LOGE,
1238 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001239 ret = -EINVAL;
1240 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 }
1242 }
1243 else
1244 {
1245 // Reset WNI_CFG_PROBE_RSP Flags
1246 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1247
1248 hddLog(VOS_TRACE_LEVEL_INFO,
1249 "%s: No Probe Response IE received in set beacon",
1250 __func__);
1251 }
1252
1253 // Added for AssocResp IE
1254 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1255 {
1256 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1257 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1258 params->assocresp_ies_len, NULL,
1259 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1260 {
1261 hddLog(LOGE,
1262 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001263 ret = -EINVAL;
1264 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 }
1266
1267 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1268 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1269 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1270 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1271 == eHAL_STATUS_FAILURE)
1272 {
1273 hddLog(LOGE,
1274 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001275 ret = -EINVAL;
1276 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001277 }
1278 }
1279 else
1280 {
1281 hddLog(VOS_TRACE_LEVEL_INFO,
1282 "%s: No Assoc Response IE received in set beacon",
1283 __func__);
1284
1285 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1286 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1287 eANI_BOOLEAN_FALSE) )
1288 {
1289 hddLog(LOGE,
1290 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1291 }
1292 }
1293
Jeff Johnsone7245742012-09-05 17:12:55 -07001294done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 vos_mem_free(genie);
1296 return 0;
1297}
Jeff Johnson295189b2012-06-20 16:38:30 -07001298
1299/*
1300 * FUNCTION: wlan_hdd_validate_operation_channel
1301 * called by wlan_hdd_cfg80211_start_bss() and
1302 * wlan_hdd_cfg80211_set_channel()
1303 * This function validates whether given channel is part of valid
1304 * channel list.
1305 */
1306static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1307{
1308
1309 v_U32_t num_ch = 0;
1310 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1311 u32 indx = 0;
1312 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +05301313 v_U8_t fValidChannel = FALSE, count = 0;
1314 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07001315
1316 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1317
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +05301318 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001319 {
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +05301320 /* Validate the channel */
1321 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 {
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +05301323 if ( channel == rfChannels[count].channelNum )
1324 {
1325 fValidChannel = TRUE;
1326 break;
1327 }
1328 }
1329 if (fValidChannel != TRUE)
1330 {
1331 hddLog(VOS_TRACE_LEVEL_ERROR,
1332 "%s: Invalid Channel [%d]", __func__, channel);
1333 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001334 }
1335 }
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +05301336 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 {
Madan Mohan Koyylamudi1803cd72013-02-05 14:07:08 +05301338 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1339 valid_ch, &num_ch))
1340 {
1341 hddLog(VOS_TRACE_LEVEL_ERROR,
1342 "%s: failed to get valid channel list", __func__);
1343 return VOS_STATUS_E_FAILURE;
1344 }
1345 for (indx = 0; indx < num_ch; indx++)
1346 {
1347 if (channel == valid_ch[indx])
1348 {
1349 break;
1350 }
1351 }
1352
1353 if (indx >= num_ch)
1354 {
1355 hddLog(VOS_TRACE_LEVEL_ERROR,
1356 "%s: Invalid Channel [%d]", __func__, channel);
1357 return VOS_STATUS_E_FAILURE;
1358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 }
1360 return VOS_STATUS_SUCCESS;
1361
1362}
1363
Viral Modi7e58d192013-02-08 11:14:52 -08001364/**
1365 * FUNCTION: wlan_hdd_cfg80211_set_channel
1366 * This function is used to set the channel number
1367 */
1368static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1369 struct ieee80211_channel *chan,
1370 enum nl80211_channel_type channel_type
1371 )
1372{
1373 v_U32_t num_ch = 0;
1374 u32 channel = 0;
1375 hdd_adapter_t *pAdapter = NULL;
1376 int freq = chan->center_freq; /* freq is in MHZ */
1377
1378 ENTER();
1379
1380 if( NULL == dev )
1381 {
1382 hddLog(VOS_TRACE_LEVEL_ERROR,
1383 "%s: Called with dev = NULL.\n", __func__);
1384 return -ENODEV;
1385 }
1386 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1387
1388 hddLog(VOS_TRACE_LEVEL_INFO,
1389 "%s: device_mode = %d freq = %d \n",__func__,
1390 pAdapter->device_mode, chan->center_freq);
1391 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1392 {
1393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1394 return -EAGAIN;
1395 }
1396
1397 /*
1398 * Do freq to chan conversion
1399 * TODO: for 11a
1400 */
1401
1402 channel = ieee80211_frequency_to_channel(freq);
1403
1404 /* Check freq range */
1405 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1406 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1407 {
1408 hddLog(VOS_TRACE_LEVEL_ERROR,
1409 "%s: Channel [%d] is outside valid range from %d to %d\n",
1410 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1411 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1412 return -EINVAL;
1413 }
1414
1415 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1416
1417 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
1418#ifdef WLAN_FEATURE_P2P
1419 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
1420#endif
1421 )
1422 {
1423 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1424 {
1425 hddLog(VOS_TRACE_LEVEL_ERROR,
1426 "%s: Invalid Channel [%d] \n", __func__, channel);
1427 return -EINVAL;
1428 }
1429 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1430 "%s: set channel to [%d] for device mode =%d",
1431 __func__, channel,pAdapter->device_mode);
1432 }
1433 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
1434#ifdef WLAN_FEATURE_P2P
1435 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
1436#endif
1437 )
1438 {
1439 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1440 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1441 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1442
1443 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1444 {
1445 /* Link is up then return cant set channel*/
1446 hddLog( VOS_TRACE_LEVEL_ERROR,
1447 "%s: IBSS Associated, can't set the channel\n", __func__);
1448 return -EINVAL;
1449 }
1450
1451 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1452 pHddStaCtx->conn_info.operationChannel = channel;
1453 pRoamProfile->ChannelInfo.ChannelList =
1454 &pHddStaCtx->conn_info.operationChannel;
1455 }
1456 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1457#ifdef WLAN_FEATURE_P2P
1458 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1459#endif
1460 )
1461 {
1462 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1463
1464 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
1465 {
1466 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1467
1468 /* If auto channel selection is configured as enable/ 1 then ignore
1469 channel set by supplicant
1470 */
1471 if ( cfg_param->apAutoChannelSelection )
1472 {
1473 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
1474
1475 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1476 "%s: set channel to auto channel (0) for device mode =%d",
1477 __func__, pAdapter->device_mode);
1478 }
1479 }
1480 }
1481 else
1482 {
1483 hddLog(VOS_TRACE_LEVEL_FATAL,
1484 "%s: Invalid device mode failed to set valid channel", __func__);
1485 return -EINVAL;
1486 }
1487 EXIT();
1488 return 0;
1489}
1490
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301491/*
1492 * FUNCTION: wlan_hdd_select_cbmode
1493 * called by wlan_hdd_cfg80211_start_bss() and
1494 * This function selects the cbmode based on primary channel
1495 */
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001496VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301497{
1498 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001499 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1500 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1501
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301502 if(
1503#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001504 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1505 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301506#endif
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001507 SapHw_mode != eSAP_DOT11_MODE_11n &&
1508 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301509 )
1510 {
1511 return VOS_STATUS_SUCCESS;
1512 }
1513
1514 if (!pConfigIni->nChannelBondingMode5GHz) {
1515 return VOS_STATUS_SUCCESS;
1516 }
1517
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001518 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301519 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1520
1521 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1522
1523#ifdef WLAN_FEATURE_11AC
1524
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001525 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1526 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301527 {
1528 if ( channel== 36 || channel == 52 || channel == 100 ||
1529 channel == 116 || channel == 149 )
1530 {
1531 smeConfig.csrConfig.channelBondingMode5GHz =
1532 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1533 }
1534 else if ( channel == 40 || channel == 56 || channel == 104 ||
1535 channel == 120 || channel == 153 )
1536 {
1537 smeConfig.csrConfig.channelBondingMode5GHz =
1538 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1539 }
1540 else if ( channel == 44 || channel == 60 || channel == 108 ||
1541 channel == 124 || channel == 157 )
1542 {
1543 smeConfig.csrConfig.channelBondingMode5GHz =
1544 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1545 }
1546 else if ( channel == 48 || channel == 64 || channel == 112 ||
1547 channel == 128 || channel == 161 )
1548 {
1549 smeConfig.csrConfig.channelBondingMode5GHz =
1550 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1551 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301552 }
1553#endif
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001554 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1555 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301556 {
1557 if ( channel== 40 || channel == 48 || channel == 56 ||
1558 channel == 64 || channel == 104 || channel == 112 ||
1559 channel == 120 || channel == 128 || channel == 136 ||
1560 channel == 144 || channel == 153 || channel == 161 )
1561 {
1562 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1563 }
1564 else if ( channel== 36 || channel == 44 || channel == 52 ||
1565 channel == 60 || channel == 100 || channel == 108 ||
1566 channel == 116 || channel == 124 || channel == 132 ||
1567 channel == 140 || channel == 149 || channel == 157 )
1568 {
1569 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1570 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301571 }
1572 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1573
1574 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1575 return VOS_STATUS_SUCCESS;
1576}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001577
Jeff Johnson295189b2012-06-20 16:38:30 -07001578#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1579static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1580 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001581#else
1582static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1583 struct cfg80211_beacon_data *params,
1584 const u8 *ssid, size_t ssid_len,
1585 enum nl80211_hidden_ssid hidden_ssid)
1586#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001587{
1588 tsap_Config_t *pConfig;
1589 beacon_data_t *pBeacon = NULL;
1590 struct ieee80211_mgmt *pMgmt_frame;
1591 v_U8_t *pIe=NULL;
1592 v_U16_t capab_info;
1593 eCsrAuthType RSNAuthType;
1594 eCsrEncryptionType RSNEncryptType;
1595 eCsrEncryptionType mcRSNEncryptType;
1596 int status = VOS_STATUS_SUCCESS;
1597 tpWLAN_SAPEventCB pSapEventCallback;
1598 hdd_hostapd_state_t *pHostapdState;
1599 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1600 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudi15462032013-02-01 11:05:57 +05301601 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 struct qc_mac_acl_entry *acl_entry = NULL;
1603 v_SINT_t i;
Madan Mohan Koyyalamudi8bca2fd2012-12-05 16:40:18 -08001604 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001605
1606 ENTER();
1607
1608 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1609
1610 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1611
1612 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1613
1614 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1615
1616 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1617
1618 //channel is already set in the set_channel Call back
1619 //pConfig->channel = pCommitConfig->channel;
1620
1621 /*Protection parameter to enable or disable*/
1622 pConfig->protEnabled =
1623 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1624
1625 pConfig->dtim_period = pBeacon->dtim_period;
1626
1627 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1628 pConfig->dtim_period);
1629
1630
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001631 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001632 {
1633 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001635 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001636 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001637 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001638 pConfig->ieee80211d = 1;
1639 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1640 sme_setRegInfo(hHal, pConfig->countryCode);
1641 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001643 else
1644 {
1645 pConfig->ieee80211d = 0;
1646 }
Madan Mohan Koyylamudi15462032013-02-01 11:05:57 +05301647 /*
1648 * If auto channel is configured i.e. channel is 0,
1649 * so skip channel validation.
1650 */
1651 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1652 {
1653 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1654 {
1655 hddLog(VOS_TRACE_LEVEL_ERROR,
1656 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1657 return -EINVAL;
1658 }
1659 }
1660 else
1661 {
1662 if(1 != pHddCtx->is_dynamic_channel_range_set)
1663 {
1664 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1665 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1666 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1667 }
1668 pHddCtx->is_dynamic_channel_range_set = 0;
1669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001671 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 {
1673 pConfig->ieee80211d = 0;
1674 }
1675 pConfig->authType = eSAP_AUTO_SWITCH;
1676
1677 capab_info = pMgmt_frame->u.beacon.capab_info;
1678
1679 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1680 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1681
1682 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1683
1684 /*Set wps station to configured*/
1685 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1686
1687 if(pIe)
1688 {
1689 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1690 {
1691 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1692 return -EINVAL;
1693 }
1694 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1695 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001696 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001697 /* Check 15 bit of WPS IE as it contain information for wps state
1698 * WPS state
1699 */
1700 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1701 {
1702 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1703 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1704 {
1705 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1706 }
1707 }
1708 }
1709 else
1710 {
1711 pConfig->wps_state = SAP_WPS_DISABLED;
1712 }
1713 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1714
1715 pConfig->RSNWPAReqIELength = 0;
1716 pConfig->pRSNWPAReqIE = NULL;
1717 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1718 WLAN_EID_RSN);
1719 if(pIe && pIe[1])
1720 {
1721 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1722 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1723 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1724 /* The actual processing may eventually be more extensive than
1725 * this. Right now, just consume any PMKIDs that are sent in
1726 * by the app.
1727 * */
1728 status = hdd_softap_unpackIE(
1729 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1730 &RSNEncryptType,
1731 &mcRSNEncryptType,
1732 &RSNAuthType,
1733 pConfig->pRSNWPAReqIE[1]+2,
1734 pConfig->pRSNWPAReqIE );
1735
1736 if( VOS_STATUS_SUCCESS == status )
1737 {
1738 /* Now copy over all the security attributes you have
1739 * parsed out
1740 * */
1741 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1742 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1743 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1744 = RSNEncryptType;
1745 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1746 "EncryptionType = %d mcEncryptionType = %d\n"),
1747 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1748 }
1749 }
1750
1751 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1752 pBeacon->tail, pBeacon->tail_len);
1753
1754 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1755 {
1756 if (pConfig->pRSNWPAReqIE)
1757 {
1758 /*Mixed mode WPA/WPA2*/
1759 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1760 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1761 }
1762 else
1763 {
1764 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1765 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1766 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1767 status = hdd_softap_unpackIE(
1768 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1769 &RSNEncryptType,
1770 &mcRSNEncryptType,
1771 &RSNAuthType,
1772 pConfig->pRSNWPAReqIE[1]+2,
1773 pConfig->pRSNWPAReqIE );
1774
1775 if( VOS_STATUS_SUCCESS == status )
1776 {
1777 /* Now copy over all the security attributes you have
1778 * parsed out
1779 * */
1780 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1781 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1782 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1783 = RSNEncryptType;
1784 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1785 "EncryptionType = %d mcEncryptionType = %d\n"),
1786 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1787 }
1788 }
1789 }
1790
1791 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1792
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001793#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 if (params->ssid != NULL)
1795 {
1796 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1797 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1798 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1799 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1800 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001801#else
1802 if (ssid != NULL)
1803 {
1804 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1805 pConfig->SSIDinfo.ssid.length = ssid_len;
1806 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1807 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1808 }
1809#endif
1810
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 vos_mem_copy(pConfig->self_macaddr.bytes,
1812 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1813
1814 /* default value */
1815 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1816 pConfig->num_accept_mac = 0;
1817 pConfig->num_deny_mac = 0;
1818
1819 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1820 pBeacon->tail, pBeacon->tail_len);
1821
1822 /* pIe for black list is following form:
1823 type : 1 byte
1824 length : 1 byte
1825 OUI : 4 bytes
1826 acl type : 1 byte
1827 no of mac addr in black list: 1 byte
1828 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1829 */
1830 if ((pIe != NULL) && (pIe[1] != 0))
1831 {
1832 pConfig->SapMacaddr_acl = pIe[6];
1833 pConfig->num_deny_mac = pIe[7];
1834 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1835 pIe[6], pIe[7]);
1836 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1837 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1838 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1839 for (i = 0; i < pConfig->num_deny_mac; i++)
1840 {
1841 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1842 acl_entry++;
1843 }
1844 }
1845 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1846 pBeacon->tail, pBeacon->tail_len);
1847
1848 /* pIe for white list is following form:
1849 type : 1 byte
1850 length : 1 byte
1851 OUI : 4 bytes
1852 acl type : 1 byte
1853 no of mac addr in white list: 1 byte
1854 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1855 */
1856 if ((pIe != NULL) && (pIe[1] != 0))
1857 {
1858 pConfig->SapMacaddr_acl = pIe[6];
1859 pConfig->num_accept_mac = pIe[7];
1860 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1861 pIe[6], pIe[7]);
1862 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1863 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1864 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1865 for (i = 0; i < pConfig->num_accept_mac; i++)
1866 {
1867 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1868 acl_entry++;
1869 }
1870 }
1871 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1872
Jeff Johnsone7245742012-09-05 17:12:55 -07001873#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnav40e89bd2013-01-15 17:09:48 -08001874 /* Overwrite the hostapd setting for HW mode only for 11ac.
1875 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1876 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1877 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1878 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1879 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1880 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1881 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001882 {
1883 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1884 }
1885#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301886
Madan Mohan Koyyalamudicca761b2012-12-04 16:41:16 -08001887 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1888 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001889 // ht_capab is not what the name conveys,this is used for protection bitmap
1890 pConfig->ht_capab =
1891 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1892
1893 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1894 {
1895 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1896 return -EINVAL;
1897 }
1898
1899 //Uapsd Enabled Bit
1900 pConfig->UapsdEnable =
1901 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1902 //Enable OBSS protection
1903 pConfig->obssProtEnabled =
1904 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1905
1906 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1907 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1908 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1909 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1910 (int)pConfig->channel);
1911 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1912 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1913 pConfig->authType);
1914 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1915 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1916 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1917 pConfig->protEnabled, pConfig->obssProtEnabled);
1918
1919 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1920 {
1921 //Bss already started. just return.
1922 //TODO Probably it should update some beacon params.
1923 hddLog( LOGE, "Bss Already started...Ignore the request");
1924 EXIT();
1925 return 0;
1926 }
1927
1928 pConfig->persona = pHostapdAdapter->device_mode;
1929
1930 pSapEventCallback = hdd_hostapd_SAPEventCB;
1931 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1932 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1933 {
1934 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1935 return -EINVAL;
1936 }
1937
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001938 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001939 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1940
1941 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1942
1943 if (!VOS_IS_STATUS_SUCCESS(status))
1944 {
1945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1946 ("ERROR: HDD vos wait for single_event failed!!\n"));
1947 VOS_ASSERT(0);
1948 }
1949
1950 //Succesfully started Bss update the state bit.
1951 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1952
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001953#ifdef WLAN_FEATURE_P2P_DEBUG
1954 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1955 {
1956 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1957 {
1958 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1959 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson3d710ea2012-12-10 14:31:52 -08001960 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001961 }
1962 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1963 {
1964 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1965 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson3d710ea2012-12-10 14:31:52 -08001966 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001967 }
1968 }
1969#endif
1970
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 pHostapdState->bCommit = TRUE;
1972 EXIT();
1973
1974 return 0;
1975}
1976
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001977#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001978static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1979 struct net_device *dev,
1980 struct beacon_parameters *params)
1981{
1982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1983 int status=VOS_STATUS_SUCCESS;
1984
1985 ENTER();
1986
1987 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1988
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001989 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1990 {
1991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1992 "%s:LOGP in Progress. Ignore!!!", __func__);
1993 return -EAGAIN;
1994 }
1995
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1997#ifdef WLAN_FEATURE_P2P
1998 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1999#endif
2000 )
2001 {
2002 beacon_data_t *old,*new;
2003
2004 old = pAdapter->sessionCtx.ap.beacon;
2005
2006 if (old)
2007 return -EALREADY;
2008
2009 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2010
2011 if(status != VOS_STATUS_SUCCESS)
2012 {
2013 hddLog(VOS_TRACE_LEVEL_FATAL,
2014 "%s:Error!!! Allocating the new beacon\n",__func__);
2015 return -EINVAL;
2016 }
2017
2018 pAdapter->sessionCtx.ap.beacon = new;
2019
2020 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2021 }
2022
2023 EXIT();
2024 return status;
2025}
2026
2027static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
2028 struct net_device *dev,
2029 struct beacon_parameters *params)
2030{
2031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2032 int status=VOS_STATUS_SUCCESS;
2033
2034 ENTER();
2035
2036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2037 __func__,pAdapter->device_mode);
2038
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002039 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2040 {
2041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2042 "%s:LOGP in Progress. Ignore!!!", __func__);
2043 return -EAGAIN;
2044 }
2045
Jeff Johnson295189b2012-06-20 16:38:30 -07002046 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2047#ifdef WLAN_FEATURE_P2P
2048 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2049#endif
2050 )
2051 {
2052 beacon_data_t *old,*new;
2053
2054 old = pAdapter->sessionCtx.ap.beacon;
2055
2056 if (!old)
2057 return -ENOENT;
2058
2059 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2060
2061 if(status != VOS_STATUS_SUCCESS) {
2062 hddLog(VOS_TRACE_LEVEL_FATAL,
2063 "%s: Error!!! Allocating the new beacon\n",__func__);
2064 return -EINVAL;
2065 }
2066
2067 pAdapter->sessionCtx.ap.beacon = new;
2068
2069 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2070 }
2071
2072 EXIT();
2073 return status;
2074}
2075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002076#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2077
2078#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002079static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2080 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002081#else
2082static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2083 struct net_device *dev)
2084#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002085{
2086 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002087 hdd_context_t *pHddCtx = NULL;
2088 hdd_scaninfo_t *pScanInfo = NULL;
2089 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 VOS_STATUS status = 0;
2091
2092 ENTER();
2093
2094 if (NULL == pAdapter)
2095 {
2096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002097 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 return -ENODEV;
2099 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002100 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2101 {
2102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2103 "%s:LOGP in Progress. Ignore!!!", __func__);
2104 return -EAGAIN;
2105 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002106
2107 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2108 if (NULL == pHddCtx)
2109 {
2110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002111 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002112 return -ENODEV;
2113 }
2114
2115 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2116 if (NULL == staAdapter)
2117 {
2118 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2119 if (NULL == staAdapter)
2120 {
2121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002122 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002123 return -ENODEV;
2124 }
2125 }
2126
2127 pScanInfo = &pHddCtx->scan_info;
2128
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2130 {
2131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2132 return -EAGAIN;
2133 }
2134
2135 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2136
2137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2138 __func__,pAdapter->device_mode);
2139
Jeff Johnsone7245742012-09-05 17:12:55 -07002140 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2141 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002142 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002143 hdd_abort_mac_scan(staAdapter->pHddCtx);
2144 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002145 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002146 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2147 if (!status)
2148 {
2149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson1920a722012-12-10 14:28:09 -08002150 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002151 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002152 VOS_ASSERT(pScanInfo->mScanPending);
2153 return 0;
2154 }
2155 }
2156
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2158#ifdef WLAN_FEATURE_P2P
2159 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2160#endif
2161 )
2162 {
2163 beacon_data_t *old;
2164
2165 old = pAdapter->sessionCtx.ap.beacon;
2166
2167 if (!old)
2168 return -ENOENT;
2169
2170#ifdef CONFIG_CFG80211
2171 hdd_cleanup_actionframe(pHddCtx, pAdapter);
2172#endif
2173
2174 mutex_lock(&pHddCtx->sap_lock);
2175 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2176 {
2177 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2178 {
2179 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2180
2181 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2182
2183 if (!VOS_IS_STATUS_SUCCESS(status))
2184 {
2185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2186 ("ERROR: HDD vos wait for single_event failed!!\n"));
2187 VOS_ASSERT(0);
2188 }
2189 }
2190 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2191 }
2192 mutex_unlock(&pHddCtx->sap_lock);
2193
2194 if(status != VOS_STATUS_SUCCESS)
2195 {
2196 hddLog(VOS_TRACE_LEVEL_FATAL,
2197 "%s:Error!!! Stopping the BSS\n",__func__);
2198 return -EINVAL;
2199 }
2200
2201 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2202 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2203 ==eHAL_STATUS_FAILURE)
2204 {
2205 hddLog(LOGE,
2206 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2207 }
2208
2209 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2210 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2211 eANI_BOOLEAN_FALSE) )
2212 {
2213 hddLog(LOGE,
2214 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2215 }
2216
2217 // Reset WNI_CFG_PROBE_RSP Flags
2218 wlan_hdd_reset_prob_rspies(pAdapter);
2219
2220 pAdapter->sessionCtx.ap.beacon = NULL;
2221 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002222#ifdef WLAN_FEATURE_P2P_DEBUG
2223 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2224 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2225 {
2226 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2227 "GO got removed");
2228 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2229 }
2230#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 }
2232 EXIT();
2233 return status;
2234}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002235
2236#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2237
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302238static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2239 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002240 struct cfg80211_ap_settings *params)
2241{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302242 hdd_adapter_t *pAdapter;
2243 hdd_context_t *pHddCtx;
2244 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002245
2246 ENTER();
2247
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302248 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002249 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2251 "%s: Device is Null", __func__);
2252 return -ENODEV;
2253 }
2254
2255 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2256 if (NULL == pAdapter)
2257 {
2258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2259 "%s: HDD adapter is Null", __func__);
2260 return -ENODEV;
2261 }
2262
2263 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2264 {
2265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2266 "%s: HDD adapter magic is invalid", __func__);
2267 return -ENODEV;
2268 }
2269
2270 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2271 if (NULL == pHddCtx)
2272 {
2273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2274 "%s: HDD context is Null", __func__);
2275 return -ENODEV;
2276 }
2277
2278 if (pHddCtx->isLogpInProgress)
2279 {
2280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2281 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002282 return -EAGAIN;
2283 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302284
2285 if (pHddCtx->isLoadUnloadInProgress)
2286 {
2287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2288 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2289 return -EAGAIN;
2290 }
2291
2292 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2293 __func__, pAdapter->device_mode);
2294
2295 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002296#ifdef WLAN_FEATURE_P2P
2297 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2298#endif
2299 )
2300 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302301 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002302
2303 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302304
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002305 if (old)
2306 return -EALREADY;
2307
2308 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2309
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302310 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002311 {
2312 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302313 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002314 return -EINVAL;
2315 }
2316 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi7e58d192013-02-08 11:14:52 -08002317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2318 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2319#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002320 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2321 params->ssid_len, params->hidden_ssid);
2322 }
2323
2324 EXIT();
2325 return status;
2326}
2327
2328
2329static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2330 struct net_device *dev,
2331 struct cfg80211_beacon_data *params)
2332{
2333 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2334 int status=VOS_STATUS_SUCCESS;
2335
2336 ENTER();
2337
2338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2339 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002340 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2341 {
2342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2343 return -EAGAIN;
2344 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345
2346 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2347#ifdef WLAN_FEATURE_P2P
2348 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2349#endif
2350 )
2351 {
2352 beacon_data_t *old,*new;
2353
2354 old = pAdapter->sessionCtx.ap.beacon;
2355
2356 if (!old)
2357 return -ENOENT;
2358
2359 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2360
2361 if(status != VOS_STATUS_SUCCESS) {
2362 hddLog(VOS_TRACE_LEVEL_FATAL,
2363 "%s: Error!!! Allocating the new beacon\n",__func__);
2364 return -EINVAL;
2365 }
2366
2367 pAdapter->sessionCtx.ap.beacon = new;
2368
2369 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2370 }
2371
2372 EXIT();
2373 return status;
2374}
2375
2376#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2377
Jeff Johnson295189b2012-06-20 16:38:30 -07002378
2379static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2380 struct net_device *dev,
2381 struct bss_parameters *params)
2382{
2383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2384
2385 ENTER();
2386
2387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2388 __func__,pAdapter->device_mode);
2389
2390 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2391#ifdef WLAN_FEATURE_P2P
2392 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2393#endif
2394 )
2395 {
2396 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2397 * want to update this parameter */
2398 if (-1 != params->ap_isolate)
2399 {
2400 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2401 }
2402 }
2403
2404 EXIT();
2405 return 0;
2406}
2407
2408/*
2409 * FUNCTION: wlan_hdd_cfg80211_change_iface
2410 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2411 */
2412int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2413 struct net_device *ndev,
2414 enum nl80211_iftype type,
2415 u32 *flags,
2416 struct vif_params *params
2417 )
2418{
2419 struct wireless_dev *wdev;
2420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2421 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002422 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 tCsrRoamProfile *pRoamProfile = NULL;
2424 eCsrRoamBssType LastBSSType;
2425 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2426 eMib_dot11DesiredBssType connectedBssType;
2427 VOS_STATUS status;
2428
2429 ENTER();
2430
2431 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2432 {
2433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2434 return -EAGAIN;
2435 }
2436
2437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2438 __func__, pAdapter->device_mode);
2439
2440 wdev = ndev->ieee80211_ptr;
2441
2442#ifdef WLAN_BTAMP_FEATURE
2443 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2444 (NL80211_IFTYPE_ADHOC == type)||
2445 (NL80211_IFTYPE_AP == type)||
2446 (NL80211_IFTYPE_P2P_GO == type))
2447 {
2448 pHddCtx->isAmpAllowed = VOS_FALSE;
2449 // stop AMP traffic
2450 status = WLANBAP_StopAmp();
2451 if(VOS_STATUS_SUCCESS != status )
2452 {
2453 pHddCtx->isAmpAllowed = VOS_TRUE;
2454 hddLog(VOS_TRACE_LEVEL_FATAL,
2455 "%s: Failed to stop AMP", __func__);
2456 return -EINVAL;
2457 }
2458 }
2459#endif //WLAN_BTAMP_FEATURE
2460 /* Reset the current device mode bit mask*/
2461 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2462
2463 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2464#ifdef WLAN_FEATURE_P2P
2465 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002466 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002467#endif
2468 )
2469 {
2470 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2471 pRoamProfile = &pWextState->roamProfile;
2472 LastBSSType = pRoamProfile->BSSType;
2473
2474 switch (type)
2475 {
2476 case NL80211_IFTYPE_STATION:
2477#ifdef WLAN_FEATURE_P2P
2478 case NL80211_IFTYPE_P2P_CLIENT:
2479#endif
2480 hddLog(VOS_TRACE_LEVEL_INFO,
2481 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2482 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002483#ifdef WLAN_FEATURE_11AC
2484 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2485 {
2486 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2487 }
2488#endif
2489 pRoamProfile->phyMode =
2490 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002491 wdev->iftype = type;
2492#ifdef WLAN_FEATURE_P2P
Gopichand Nakkala310362f2012-12-31 16:35:10 -08002493 //Check for sub-string p2p to confirm its a p2p interface
2494 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkalaad9ed1a2012-12-31 16:08:51 -08002495 {
2496 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2497 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2498 }
2499 else
2500 {
2501 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002502 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkalaad9ed1a2012-12-31 16:08:51 -08002503 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002504#endif
2505 break;
2506 case NL80211_IFTYPE_ADHOC:
2507 hddLog(VOS_TRACE_LEVEL_INFO,
2508 "%s: setting interface Type to ADHOC", __func__);
2509 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2510 pRoamProfile->phyMode =
2511 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2512 wdev->iftype = type;
2513 break;
2514
2515 case NL80211_IFTYPE_AP:
2516#ifdef WLAN_FEATURE_P2P
2517 case NL80211_IFTYPE_P2P_GO:
2518#endif
2519 {
2520 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2521 "%s: setting interface Type to %s", __func__,
2522 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2523
Gopichand Nakkala310362f2012-12-31 16:35:10 -08002524 //Cancel any remain on channel for GO mode
2525 if (NL80211_IFTYPE_P2P_GO == type)
2526 {
2527 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2528 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002529 if (NL80211_IFTYPE_AP == type)
2530 {
2531 /* As Loading WLAN Driver one interface being created for p2p device
2532 * address. This will take one HW STA and the max number of clients
2533 * that can connect to softAP will be reduced by one. so while changing
2534 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2535 * interface as it is not required in SoftAP mode.
2536 */
2537
2538 // Get P2P Adapter
2539 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2540
2541 if (pP2pAdapter)
2542 {
2543 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2544 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2545 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2546 }
2547 }
2548
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 //De-init the adapter.
2550 hdd_stop_adapter( pHddCtx, pAdapter );
2551 hdd_deinit_adapter( pHddCtx, pAdapter );
2552 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2553#ifdef WLAN_SOFTAP_FEATURE
2554#ifdef WLAN_FEATURE_P2P
2555 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2556 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2557#else
2558 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2559#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002560
2561 //Disable BMPS and IMPS if enabled
2562 //before starting Go
2563 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2564 {
2565 if(VOS_STATUS_E_FAILURE ==
2566 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2567 {
2568 //Fail to Exit BMPS
2569 VOS_ASSERT(0);
2570 }
2571 }
2572
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002573 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2574 (pConfig->apRandomBssidEnabled))
2575 {
2576 /* To meet Android requirements create a randomized
2577 MAC address of the form 02:1A:11:Fx:xx:xx */
2578 get_random_bytes(&ndev->dev_addr[3], 3);
2579 ndev->dev_addr[0] = 0x02;
2580 ndev->dev_addr[1] = 0x1A;
2581 ndev->dev_addr[2] = 0x11;
2582 ndev->dev_addr[3] |= 0xF0;
2583 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2584 VOS_MAC_ADDR_SIZE);
2585 pr_info("wlan: Generated HotSpot BSSID "
2586 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2587 ndev->dev_addr[0],
2588 ndev->dev_addr[1],
2589 ndev->dev_addr[2],
2590 ndev->dev_addr[3],
2591 ndev->dev_addr[4],
2592 ndev->dev_addr[5]);
2593 }
2594
Jeff Johnson295189b2012-06-20 16:38:30 -07002595 hdd_set_ap_ops( pAdapter->dev );
2596
2597 status = hdd_init_ap_mode(pAdapter);
2598 if(status != VOS_STATUS_SUCCESS)
2599 {
2600 hddLog(VOS_TRACE_LEVEL_FATAL,
2601 "%s: Error initializing the ap mode", __func__);
2602 return -EINVAL;
2603 }
2604 hdd_set_conparam(1);
2605
2606#endif
2607 /*interface type changed update in wiphy structure*/
2608 if(wdev)
2609 {
2610 wdev->iftype = type;
2611 pHddCtx->change_iface = type;
2612 }
2613 else
2614 {
2615 hddLog(VOS_TRACE_LEVEL_ERROR,
2616 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2617 return -EINVAL;
2618 }
2619 goto done;
2620 }
2621
2622 default:
2623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2624 __func__);
2625 return -EOPNOTSUPP;
2626 }
2627 }
2628 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2629#ifdef WLAN_FEATURE_P2P
2630 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2631#endif
2632 )
2633 {
2634 switch(type)
2635 {
2636 case NL80211_IFTYPE_STATION:
2637#ifdef WLAN_FEATURE_P2P
2638 case NL80211_IFTYPE_P2P_CLIENT:
2639#endif
2640 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002641 hdd_stop_adapter( pHddCtx, pAdapter );
2642 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002643 wdev->iftype = type;
2644#ifdef WLAN_FEATURE_P2P
Gopichand Nakkala310362f2012-12-31 16:35:10 -08002645 //Check for sub-string p2p to confirm its a p2p interface
2646 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkalaad9ed1a2012-12-31 16:08:51 -08002647 {
2648 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2649 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2650 }
2651 else
2652 {
2653 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002654 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkalaad9ed1a2012-12-31 16:08:51 -08002655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002656#endif
2657 hdd_set_conparam(0);
2658 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002659 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2660 hdd_set_station_ops( pAdapter->dev );
2661 status = hdd_init_station_mode( pAdapter );
2662 if( VOS_STATUS_SUCCESS != status )
2663 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002664 /* In case of JB, for P2P-GO, only change interface will be called,
2665 * This is the right place to enable back bmps_imps()
2666 */
2667 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 goto done;
2669 case NL80211_IFTYPE_AP:
2670#ifdef WLAN_FEATURE_P2P
2671 case NL80211_IFTYPE_P2P_GO:
2672#endif
2673 wdev->iftype = type;
2674#ifdef WLAN_FEATURE_P2P
2675 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2676 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2677#endif
2678 goto done;
2679 default:
2680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2681 __func__);
2682 return -EOPNOTSUPP;
2683
2684 }
2685
2686 }
2687 else
2688 {
2689 return -EOPNOTSUPP;
2690 }
2691
2692
2693 if(pRoamProfile)
2694 {
2695 if ( LastBSSType != pRoamProfile->BSSType )
2696 {
2697 /*interface type changed update in wiphy structure*/
2698 wdev->iftype = type;
2699
2700 /*the BSS mode changed, We need to issue disconnect
2701 if connected or in IBSS disconnect state*/
2702 if ( hdd_connGetConnectedBssType(
2703 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2704 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2705 {
2706 /*need to issue a disconnect to CSR.*/
2707 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2708 if( eHAL_STATUS_SUCCESS ==
2709 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2710 pAdapter->sessionId,
2711 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2712 {
2713 wait_for_completion_interruptible_timeout(
2714 &pAdapter->disconnect_comp_var,
2715 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2716 }
2717 }
2718 }
2719 }
2720
2721done:
2722 /*set bitmask based on updated value*/
2723 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2724#ifdef WLAN_BTAMP_FEATURE
2725 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2726 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2727 {
2728 //we are ok to do AMP
2729 pHddCtx->isAmpAllowed = VOS_TRUE;
2730 }
2731#endif //WLAN_BTAMP_FEATURE
2732 EXIT();
2733 return 0;
2734}
2735
2736static int wlan_hdd_change_station(struct wiphy *wiphy,
2737 struct net_device *dev,
2738 u8 *mac,
2739 struct station_parameters *params)
2740{
2741 VOS_STATUS status = VOS_STATUS_SUCCESS;
2742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2743 v_MACADDR_t STAMacAddress;
2744
Jeff Johnsone7245742012-09-05 17:12:55 -07002745 ENTER();
2746
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002747 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2748 {
2749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2750 "%s:LOGP in Progress. Ignore!!!", __func__);
2751 return -EAGAIN;
2752 }
2753
Jeff Johnson295189b2012-06-20 16:38:30 -07002754 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2755
2756 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2757#ifdef WLAN_FEATURE_P2P
2758 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2759#endif
2760 )
2761 {
2762 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2763 {
2764 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2765 WLANTL_STA_AUTHENTICATED);
2766
2767 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002768 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002769 return -EINVAL;
2770 }
2771 }
2772
Jeff Johnsone7245742012-09-05 17:12:55 -07002773 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002774 return status;
2775}
2776
2777/*
2778 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2779 * This function is used to get peer station index in IBSS mode
2780 */
2781static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2782{
2783 u8 idx = 0;
2784 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2785 ENTER();
2786 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2787 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2788 {
2789 if ( (0 !=
2790 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2791 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2792 temp, VOS_MAC_ADDR_SIZE)
2793 )
2794 {
2795 return idx;
2796 }
2797 }
2798 return idx;
2799}
2800
2801
2802/*
2803 * FUNCTION: wlan_hdd_cfg80211_add_key
2804 * This function is used to initialize the key information
2805 */
2806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2807static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2808 struct net_device *ndev,
2809 u8 key_index, bool pairwise,
2810 const u8 *mac_addr,
2811 struct key_params *params
2812 )
2813#else
2814static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2815 struct net_device *ndev,
2816 u8 key_index, const u8 *mac_addr,
2817 struct key_params *params
2818 )
2819#endif
2820{
2821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2822 tCsrRoamSetKey setKey;
2823 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2824 int status = 0;
2825 v_U32_t roamId= 0xFF;
2826 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2827 hdd_hostapd_state_t *pHostapdState;
2828 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002829 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002830
2831 ENTER();
2832
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002833 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2834 {
2835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2836 "%s:LOGP in Progress. Ignore!!!", __func__);
2837 return -EAGAIN;
2838 }
2839
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2841 __func__,pAdapter->device_mode);
2842
2843 if (CSR_MAX_NUM_KEY <= key_index)
2844 {
2845 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2846 key_index);
2847
2848 return -EINVAL;
2849 }
2850
2851 hddLog(VOS_TRACE_LEVEL_INFO,
2852 "%s: called with key index = %d & key length %d",
2853 __func__, key_index, params->key_len);
2854
2855 /*extract key idx, key len and key*/
2856 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2857 setKey.keyId = key_index;
2858 setKey.keyLength = params->key_len;
2859 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2860
2861 switch (params->cipher)
2862 {
2863 case WLAN_CIPHER_SUITE_WEP40:
2864 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2865 break;
2866
2867 case WLAN_CIPHER_SUITE_WEP104:
2868 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2869 break;
2870
2871 case WLAN_CIPHER_SUITE_TKIP:
2872 {
2873 u8 *pKey = &setKey.Key[0];
2874 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2875
2876 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2877
2878 /*Supplicant sends the 32bytes key in this order
2879
2880 |--------------|----------|----------|
2881 | Tk1 |TX-MIC | RX Mic |
2882 |--------------|----------|----------|
2883 <---16bytes---><--8bytes--><--8bytes-->
2884
2885 */
2886 /*Sme expects the 32 bytes key to be in the below order
2887
2888 |--------------|----------|----------|
2889 | Tk1 |RX-MIC | TX Mic |
2890 |--------------|----------|----------|
2891 <---16bytes---><--8bytes--><--8bytes-->
2892 */
2893 /* Copy the Temporal Key 1 (TK1) */
2894 vos_mem_copy(pKey, params->key,16);
2895
2896 /*Copy the rx mic first*/
2897 vos_mem_copy(&pKey[16],&params->key[24],8);
2898
2899 /*Copy the tx mic */
2900 vos_mem_copy(&pKey[24],&params->key[16],8);
2901
2902
2903 break;
2904 }
2905
2906 case WLAN_CIPHER_SUITE_CCMP:
2907 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2908 break;
2909
2910#ifdef FEATURE_WLAN_WAPI
2911 case WLAN_CIPHER_SUITE_SMS4:
2912 {
2913 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2914 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2915 params->key, params->key_len);
2916 return 0;
2917 }
2918#endif
2919#ifdef FEATURE_WLAN_CCX
2920 case WLAN_CIPHER_SUITE_KRK:
2921 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2922 break;
2923#endif
2924 default:
2925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2926 __func__, params->cipher);
2927 return -EOPNOTSUPP;
2928 }
2929
2930 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2931 __func__, setKey.encType);
2932
2933
2934
2935 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2936#ifdef WLAN_FEATURE_P2P
2937 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2938#endif
2939 )
2940 {
2941
2942
2943 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,
Jeff Johnson3d710ea2012-12-10 14:31:52 -08002953 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002954 __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 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2969 if( pHostapdState->bssState == BSS_START )
2970 {
2971 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2972
2973 if ( status != eHAL_STATUS_SUCCESS )
2974 {
2975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2976 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2977 __LINE__, status );
2978 }
2979 }
2980
2981 /* Saving WEP keys */
2982 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2983 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2984 {
2985 //Save the wep key in ap context. Issue setkey after the BSS is started.
2986 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2987 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2988 }
2989 else
2990 {
2991 //Save the key in ap context. Issue setkey after the BSS is started.
2992 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2993 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2994 }
2995 }
2996 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2997#ifdef WLAN_FEATURE_P2P
2998 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2999#endif
3000 )
3001 {
3002 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3003 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3004
3005 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3006
Venkata Prathyusha Kuntupalli584507e2013-01-17 14:09:24 -08003007 pWextState->roamProfile.Keys.defaultIndex = key_index;
3008
3009
Jeff Johnson295189b2012-06-20 16:38:30 -07003010 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3011 params->key, params->key_len);
3012
3013 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3014
3015 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3016 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3017 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3018 )
3019 &&
3020 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3021 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3022 )
3023 )
3024 {
3025 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3026 * interface, copy bssid for pairwise key and group macaddr for
3027 * group key initialization*/
3028
3029 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3030
3031 pWextState->roamProfile.negotiatedUCEncryptionType =
3032 pHddStaCtx->conn_info.ucEncryptionType =
3033 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3034 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3035 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3036
3037
3038 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3039 "%s: Negotiated encryption type %d", __func__,
3040 pWextState->roamProfile.negotiatedUCEncryptionType);
3041
3042 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3043 &pWextState->roamProfile, true);
3044 setKey.keyLength = 0;
3045 setKey.keyDirection = eSIR_TX_RX;
3046
3047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3048 if (pairwise)
3049 {
3050#endif
3051 if (mac_addr)
3052 {
3053 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3054 }
3055 else
3056 {
3057 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3058 * and peerMacAddress in case of IBSS*/
3059 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3060 {
3061 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3062 if (HDD_MAX_NUM_IBSS_STA != staidx)
3063 {
3064 vos_mem_copy(setKey.peerMac,
3065 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3066 WNI_CFG_BSSID_LEN);
3067
3068 }
3069 else
3070 {
3071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3072 __func__);
3073 return -EOPNOTSUPP;
3074 }
3075 }
3076 else
3077 {
3078 vos_mem_copy(setKey.peerMac,
3079 &pHddStaCtx->conn_info.bssId[0],
3080 WNI_CFG_BSSID_LEN);
3081 }
3082 }
3083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3084 }
3085 else
3086 {
3087 /* set group key*/
3088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3089 "%s- %d: setting Group key",
3090 __func__, __LINE__);
3091 setKey.keyDirection = eSIR_RX_ONLY;
3092 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3093 }
3094#endif
3095 }
3096 else if (
3097#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3098 (!pairwise)
3099#else
3100 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3101#endif
3102 )
3103 {
3104 /* set group key*/
3105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3106 "%s- %d: setting Group key",
3107 __func__, __LINE__);
3108 setKey.keyDirection = eSIR_RX_ONLY;
3109 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3110 }
3111 else
3112 {
3113 /* set pairwise key*/
3114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3115 "%s- %d: setting pairwise key",
3116 __func__, __LINE__);
3117 setKey.keyDirection = eSIR_TX_RX;
3118 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3119 }
3120
3121 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3122 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3123 __func__, setKey.peerMac[0], setKey.peerMac[1],
3124 setKey.peerMac[2], setKey.peerMac[3],
3125 setKey.peerMac[4], setKey.peerMac[5],
3126 setKey.keyDirection);
3127
3128 vos_status = wlan_hdd_check_ula_done(pAdapter);
3129
3130 if ( vos_status != VOS_STATUS_SUCCESS )
3131 {
3132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3133 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3134 __LINE__, vos_status );
3135
3136 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3137
3138 return -EINVAL;
3139
3140 }
3141
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003142#ifdef WLAN_FEATURE_VOWIFI_11R
3143 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3144 Save the key in the UMAC and include it in the ADD BSS request */
3145 /*TODO 11r - is this used?? */
3146 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
3147 if( halStatus == eHAL_STATUS_SUCCESS )
3148 {
3149 return halStatus;
3150 }
3151#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003152
3153 /* issue set key request to SME*/
3154 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3155 pAdapter->sessionId, &setKey, &roamId );
3156
3157 if ( 0 != status )
3158 {
3159 hddLog(VOS_TRACE_LEVEL_ERROR,
3160 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3161 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3162 return -EINVAL;
3163 }
3164
3165
3166 /* in case of IBSS as there was no information available about WEP keys during
3167 * IBSS join, group key intialized with NULL key, so re-initialize group key
3168 * with correct value*/
3169 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3170 !( ( IW_AUTH_KEY_MGMT_802_1X
3171 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3172 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3173 )
3174 &&
3175 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3176 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3177 )
3178 )
3179 {
3180 setKey.keyDirection = eSIR_RX_ONLY;
3181 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3182
3183 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3184 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3185 __func__, setKey.peerMac[0], setKey.peerMac[1],
3186 setKey.peerMac[2], setKey.peerMac[3],
3187 setKey.peerMac[4], setKey.peerMac[5],
3188 setKey.keyDirection);
3189
3190 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3191 pAdapter->sessionId, &setKey, &roamId );
3192
3193 if ( 0 != status )
3194 {
3195 hddLog(VOS_TRACE_LEVEL_ERROR,
3196 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3197 __func__, status);
3198 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3199 return -EINVAL;
3200 }
3201 }
3202 }
3203
3204 return 0;
3205}
3206
3207/*
3208 * FUNCTION: wlan_hdd_cfg80211_get_key
3209 * This function is used to get the key information
3210 */
3211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3212static int wlan_hdd_cfg80211_get_key(
3213 struct wiphy *wiphy,
3214 struct net_device *ndev,
3215 u8 key_index, bool pairwise,
3216 const u8 *mac_addr, void *cookie,
3217 void (*callback)(void *cookie, struct key_params*)
3218 )
3219#else
3220static int wlan_hdd_cfg80211_get_key(
3221 struct wiphy *wiphy,
3222 struct net_device *ndev,
3223 u8 key_index, const u8 *mac_addr, void *cookie,
3224 void (*callback)(void *cookie, struct key_params*)
3225 )
3226#endif
3227{
3228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3229 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3230 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3231 struct key_params params;
3232
3233 ENTER();
3234
3235 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3236 __func__,pAdapter->device_mode);
3237
3238 memset(&params, 0, sizeof(params));
3239
3240 if (CSR_MAX_NUM_KEY <= key_index)
3241 {
3242 return -EINVAL;
3243 }
3244
3245 switch(pRoamProfile->EncryptionType.encryptionType[0])
3246 {
3247 case eCSR_ENCRYPT_TYPE_NONE:
3248 params.cipher = IW_AUTH_CIPHER_NONE;
3249 break;
3250
3251 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3252 case eCSR_ENCRYPT_TYPE_WEP40:
3253 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3254 break;
3255
3256 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3257 case eCSR_ENCRYPT_TYPE_WEP104:
3258 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3259 break;
3260
3261 case eCSR_ENCRYPT_TYPE_TKIP:
3262 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3263 break;
3264
3265 case eCSR_ENCRYPT_TYPE_AES:
3266 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3267 break;
3268
3269 default:
3270 params.cipher = IW_AUTH_CIPHER_NONE;
3271 break;
3272 }
3273
3274 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3275 params.seq_len = 0;
3276 params.seq = NULL;
3277 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3278 callback(cookie, &params);
3279 return 0;
3280}
3281
3282/*
3283 * FUNCTION: wlan_hdd_cfg80211_del_key
3284 * This function is used to delete the key information
3285 */
3286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3287static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3288 struct net_device *ndev,
3289 u8 key_index,
3290 bool pairwise,
3291 const u8 *mac_addr
3292 )
3293#else
3294static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3295 struct net_device *ndev,
3296 u8 key_index,
3297 const u8 *mac_addr
3298 )
3299#endif
3300{
3301 int status = 0;
3302
3303 //This code needs to be revisited. There is sme_removeKey API, we should
3304 //plan to use that. After the change to use correct index in setkey,
3305 //it is observed that this is invalidating peer
3306 //key index whenever re-key is done. This is affecting data link.
3307 //It should be ok to ignore del_key.
3308#if 0
3309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3310 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3311 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3312 tCsrRoamSetKey setKey;
3313 v_U32_t roamId= 0xFF;
3314
3315 ENTER();
3316
3317 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3318 __func__,pAdapter->device_mode);
3319
3320 if (CSR_MAX_NUM_KEY <= key_index)
3321 {
3322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3323 key_index);
3324
3325 return -EINVAL;
3326 }
3327
3328 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3329 setKey.keyId = key_index;
3330
3331 if (mac_addr)
3332 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3333 else
3334 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3335
3336 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3337
3338 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3339#ifdef WLAN_FEATURE_P2P
3340 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3341#endif
3342 )
3343 {
3344
3345 hdd_hostapd_state_t *pHostapdState =
3346 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3347 if( pHostapdState->bssState == BSS_START)
3348 {
3349 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3350
3351 if ( status != eHAL_STATUS_SUCCESS )
3352 {
3353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3354 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3355 __LINE__, status );
3356 }
3357 }
3358 }
3359 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3360#ifdef WLAN_FEATURE_P2P
3361 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3362#endif
3363 )
3364 {
3365 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3366
3367 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3368
3369 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3370 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3371 __func__, setKey.peerMac[0], setKey.peerMac[1],
3372 setKey.peerMac[2], setKey.peerMac[3],
3373 setKey.peerMac[4], setKey.peerMac[5]);
3374 if(pAdapter->sessionCtx.station.conn_info.connState ==
3375 eConnectionState_Associated)
3376 {
3377 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3378 pAdapter->sessionId, &setKey, &roamId );
3379
3380 if ( 0 != status )
3381 {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 "%s: sme_RoamSetKey failure, returned %d",
3384 __func__, status);
3385 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3386 return -EINVAL;
3387 }
3388 }
3389 }
3390#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003391 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003392 return status;
3393}
3394
3395/*
3396 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3397 * This function is used to set the default tx key index
3398 */
3399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3400static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3401 struct net_device *ndev,
3402 u8 key_index,
3403 bool unicast, bool multicast)
3404#else
3405static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3406 struct net_device *ndev,
3407 u8 key_index)
3408#endif
3409{
3410 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3411 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3412 int status = 0;
3413 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3414
3415 ENTER();
3416
3417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3418 __func__,pAdapter->device_mode, key_index);
3419
3420 if (CSR_MAX_NUM_KEY <= key_index)
3421 {
3422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3423 key_index);
3424
3425 return -EINVAL;
3426 }
3427
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003428 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3429 {
3430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3431 "%s:LOGP in Progress. Ignore!!!", __func__);
3432 return -EAGAIN;
3433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003434
3435 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3436#ifdef WLAN_FEATURE_P2P
3437 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3438#endif
3439 )
3440 {
3441 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3442 (eCSR_ENCRYPT_TYPE_TKIP !=
3443 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3444 (eCSR_ENCRYPT_TYPE_AES !=
3445 pWextState->roamProfile.EncryptionType.encryptionType[0])
3446 )
3447 {
3448 /* if default key index is not same as previous one,
3449 * then update the default key index */
3450
3451 tCsrRoamSetKey setKey;
3452 v_U32_t roamId= 0xFF;
3453 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3454
3455 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3456 __func__, key_index);
3457
3458 Keys->defaultIndex = (u8)key_index;
3459 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3460 setKey.keyId = key_index;
3461 setKey.keyLength = Keys->KeyLength[key_index];
3462
3463 vos_mem_copy(&setKey.Key[0],
3464 &Keys->KeyMaterial[key_index][0],
3465 Keys->KeyLength[key_index]);
3466
3467 setKey.keyDirection = eSIR_TX_ONLY;
3468
3469 vos_mem_copy(setKey.peerMac,
3470 &pHddStaCtx->conn_info.bssId[0],
3471 WNI_CFG_BSSID_LEN);
3472
3473 setKey.encType =
3474 pWextState->roamProfile.EncryptionType.encryptionType[0];
3475
3476 /* issue set key request */
3477 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3478 pAdapter->sessionId, &setKey, &roamId );
3479
3480 if ( 0 != status )
3481 {
3482 hddLog(VOS_TRACE_LEVEL_ERROR,
3483 "%s: sme_RoamSetKey failed, returned %d", __func__,
3484 status);
3485 return -EINVAL;
3486 }
3487 }
3488 }
3489
3490 /* In SoftAp mode setting key direction for default mode */
3491 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3492 {
3493 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3494 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3495 (eCSR_ENCRYPT_TYPE_AES !=
3496 pWextState->roamProfile.EncryptionType.encryptionType[0])
3497 )
3498 {
3499 /* Saving key direction for default key index to TX default */
3500 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3501 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3502 }
3503 }
3504
3505 return status;
3506}
3507
Jeff Johnson295189b2012-06-20 16:38:30 -07003508/*
3509 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3510 * This function is used to inform the BSS details to nl80211 interface.
3511 */
3512static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3513 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3514{
3515 struct net_device *dev = pAdapter->dev;
3516 struct wireless_dev *wdev = dev->ieee80211_ptr;
3517 struct wiphy *wiphy = wdev->wiphy;
3518 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3519 int chan_no;
3520 int ie_length;
3521 const char *ie;
3522 unsigned int freq;
3523 struct ieee80211_channel *chan;
3524 int rssi = 0;
3525 struct cfg80211_bss *bss = NULL;
3526
3527 ENTER();
3528
3529 if( NULL == pBssDesc )
3530 {
3531 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3532 return bss;
3533 }
3534
3535 chan_no = pBssDesc->channelId;
3536 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3537 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3538
3539 if( NULL == ie )
3540 {
3541 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3542 return bss;
3543 }
3544
3545#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3546 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3547 {
3548 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3549 }
3550 else
3551 {
3552 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3553 }
3554#else
3555 freq = ieee80211_channel_to_frequency(chan_no);
3556#endif
3557
3558 chan = __ieee80211_get_channel(wiphy, freq);
3559
3560 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3561 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3562 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3563 if (bss == NULL)
3564 {
3565 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3566
3567 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3568 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3569 pBssDesc->capabilityInfo,
3570 pBssDesc->beaconInterval, ie, ie_length,
3571 rssi, GFP_KERNEL ));
3572}
3573 else
3574 {
3575 return bss;
3576 }
3577}
3578
3579
3580
3581/*
3582 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3583 * This function is used to inform the BSS details to nl80211 interface.
3584 */
3585struct cfg80211_bss*
3586wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3587 tSirBssDescription *bss_desc
3588 )
3589{
3590 /*
3591 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3592 already exists in bss data base of cfg80211 for that particular BSS ID.
3593 Using cfg80211_inform_bss_frame to update the bss entry instead of
3594 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3595 now there is no possibility to get the mgmt(probe response) frame from PE,
3596 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3597 cfg80211_inform_bss_frame.
3598 */
3599 struct net_device *dev = pAdapter->dev;
3600 struct wireless_dev *wdev = dev->ieee80211_ptr;
3601 struct wiphy *wiphy = wdev->wiphy;
3602 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003603#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3604 qcom_ie_age *qie_age = NULL;
3605 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3606#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003607 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003608#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003609 const char *ie =
3610 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3611 unsigned int freq;
3612 struct ieee80211_channel *chan;
3613 struct ieee80211_mgmt *mgmt =
3614 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3615 struct cfg80211_bss *bss_status = NULL;
3616 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3617 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003618#ifdef WLAN_OPEN_SOURCE
3619 struct timespec ts;
3620#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003621
3622 ENTER();
3623
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003624 if (!mgmt)
3625 return NULL;
3626
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003628
3629#ifdef WLAN_OPEN_SOURCE
3630 /* Android does not want the timestamp from the frame.
3631 Instead it wants a monotonic increasing value */
3632 get_monotonic_boottime(&ts);
3633 mgmt->u.probe_resp.timestamp =
3634 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3635#else
3636 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3638 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003639
3640#endif
3641
Jeff Johnson295189b2012-06-20 16:38:30 -07003642 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3643 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003644
3645#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3646 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3647 /* Assuming this is the last IE, copy at the end */
3648 ie_length -=sizeof(qcom_ie_age);
3649 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3650 qie_age->element_id = QCOM_VENDOR_IE_ID;
3651 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3652 qie_age->oui_1 = QCOM_OUI1;
3653 qie_age->oui_2 = QCOM_OUI2;
3654 qie_age->oui_3 = QCOM_OUI3;
3655 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3656 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3657#endif
3658
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3660
3661 mgmt->frame_control |=
3662 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3663
3664#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3665 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3666 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3667 {
3668 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3669 }
3670 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3671 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3672
3673 {
3674 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3675 }
3676 else
3677 {
3678 kfree(mgmt);
3679 return NULL;
3680 }
3681#else
3682 freq = ieee80211_channel_to_frequency(chan_no);
3683#endif
3684 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy47f0ff22013-01-24 18:33:30 -08003685 /*when the band is changed on the fly using the GUI, three things are done
3686 * 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)
3687 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3688 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3689 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3690 * and discards the channels correponding to previous band and calls back with zero bss results.
3691 * 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
3692 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3693 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3694 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3695 * So drop the bss and continue to next bss.
3696 */
3697 if(chan == NULL)
3698 {
3699 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3700 return NULL;
3701 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003702 /*To keep the rssi icon of the connected AP in the scan window
3703 *and the rssi icon of the wireless networks in sync
3704 * */
3705 if (( eConnectionState_Associated ==
3706 pAdapter->sessionCtx.station.conn_info.connState ) &&
3707 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3708 pAdapter->sessionCtx.station.conn_info.bssId,
3709 WNI_CFG_BSSID_LEN)))
3710 {
3711 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3712 rssi = (pAdapter->rssi * 100);
3713 }
3714 else
3715 {
3716 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3717 }
3718
3719 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3720 frame_len, rssi, GFP_KERNEL);
3721 kfree(mgmt);
3722 return bss_status;
3723}
3724
3725/*
3726 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3727 * This function is used to update the BSS data base of CFG8011
3728 */
3729struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3730 tCsrRoamInfo *pRoamInfo
3731 )
3732{
3733 tCsrRoamConnectedProfile roamProfile;
3734 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3735 struct cfg80211_bss *bss = NULL;
3736
3737 ENTER();
3738
3739 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3740 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3741
3742 if (NULL != roamProfile.pBssDesc)
3743 {
3744 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3745 &roamProfile);
3746
3747 if (NULL == bss)
3748 {
3749 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3750 __func__);
3751 }
3752
3753 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3754 }
3755 else
3756 {
3757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3758 __func__);
3759 }
3760 return bss;
3761}
3762
3763/*
3764 * FUNCTION: wlan_hdd_cfg80211_update_bss
3765 */
3766static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3767 hdd_adapter_t *pAdapter
3768 )
3769{
3770 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3771 tCsrScanResultInfo *pScanResult;
3772 eHalStatus status = 0;
3773 tScanResultHandle pResult;
3774 struct cfg80211_bss *bss_status = NULL;
3775
3776 ENTER();
3777
3778 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3779 {
3780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3781 return -EAGAIN;
3782 }
3783
3784 /*
3785 * start getting scan results and populate cgf80211 BSS database
3786 */
3787 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3788
3789 /* no scan results */
3790 if (NULL == pResult)
3791 {
3792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3793 return status;
3794 }
3795
3796 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3797
3798 while (pScanResult)
3799 {
3800 /*
3801 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3802 * entry already exists in bss data base of cfg80211 for that
3803 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3804 * bss entry instead of cfg80211_inform_bss, But this call expects
3805 * mgmt packet as input. As of now there is no possibility to get
3806 * the mgmt(probe response) frame from PE, converting bss_desc to
3807 * ieee80211_mgmt(probe response) and passing to c
3808 * fg80211_inform_bss_frame.
3809 * */
3810
3811 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3812 &pScanResult->BssDescriptor);
3813
3814
3815 if (NULL == bss_status)
3816 {
3817 hddLog(VOS_TRACE_LEVEL_INFO,
3818 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3819 }
3820 else
3821 {
3822 cfg80211_put_bss(bss_status);
3823 }
3824
3825 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3826 }
3827
3828 sme_ScanResultPurge(hHal, pResult);
3829
3830 return 0;
3831}
3832
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003833void
3834hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3835{
3836 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003837 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3838 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3839 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003840} /****** end hddPrintMacAddr() ******/
3841
3842void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003843hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003844{
3845 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003846 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3847 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3848 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3849 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003850} /****** end hddPrintPmkId() ******/
3851
3852//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3853//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3854
3855//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3856//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3857
3858#define dump_bssid(bssid) \
3859 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003860 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3861 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3862 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003863 }
3864
3865#define dump_pmkid(pMac, pmkid) \
3866 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003867 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3868 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3869 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003870 }
3871
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003872#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003873/*
3874 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3875 * This function is used to notify the supplicant of a new PMKSA candidate.
3876 */
3877int wlan_hdd_cfg80211_pmksa_candidate_notify(
3878 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3879 int index, bool preauth )
3880{
Jeff Johnsone7245742012-09-05 17:12:55 -07003881#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003882 struct net_device *dev = pAdapter->dev;
3883
3884 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003885 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003886
3887 if( NULL == pRoamInfo )
3888 {
3889 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3890 return -EINVAL;
3891 }
3892
3893 dump_bssid(pRoamInfo->bssid);
3894 cfg80211_pmksa_candidate_notify(dev, index,
3895 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003896#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003897 return 0;
3898}
3899#endif //FEATURE_WLAN_LFR
3900
Jeff Johnson295189b2012-06-20 16:38:30 -07003901/*
3902 * FUNCTION: hdd_cfg80211_scan_done_callback
3903 * scanning callback function, called after finishing scan
3904 *
3905 */
3906static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3907 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3908{
3909 struct net_device *dev = (struct net_device *) pContext;
3910 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003912 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3913 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 struct cfg80211_scan_request *req = NULL;
3915 int ret = 0;
3916
3917 ENTER();
3918
3919 hddLog(VOS_TRACE_LEVEL_INFO,
3920 "%s called with halHandle = %p, pContext = %p,"
3921 "scanID = %d, returned status = %d\n",
3922 __func__, halHandle, pContext, (int) scanId, (int) status);
3923
3924 //Block on scan req completion variable. Can't wait forever though.
3925 ret = wait_for_completion_interruptible_timeout(
3926 &pScanInfo->scan_req_completion_event,
3927 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3928 if (!ret)
3929 {
3930 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003931 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 }
3933
3934 if(pScanInfo->mScanPending != VOS_TRUE)
3935 {
3936 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003937 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 }
3939
3940 /* Check the scanId */
3941 if (pScanInfo->scanId != scanId)
3942 {
3943 hddLog(VOS_TRACE_LEVEL_INFO,
3944 "%s called with mismatched scanId pScanInfo->scanId = %d "
3945 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3946 (int) scanId);
3947 }
3948
Jeff Johnson295189b2012-06-20 16:38:30 -07003949 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3950 pAdapter);
3951
3952 if (0 > ret)
3953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3954
3955
3956 /* If any client wait scan result through WEXT
3957 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003958 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003959 {
3960 /* The other scan request waiting for current scan finish
3961 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003962 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003964 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003965 }
3966 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003967 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 {
3969 struct net_device *dev = pAdapter->dev;
3970 union iwreq_data wrqu;
3971 int we_event;
3972 char *msg;
3973
3974 memset(&wrqu, '\0', sizeof(wrqu));
3975 we_event = SIOCGIWSCAN;
3976 msg = NULL;
3977 wireless_send_event(dev, we_event, &wrqu, msg);
3978 }
3979 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003980 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003981
3982 /* Get the Scan Req */
3983 req = pAdapter->request;
3984
3985 if (!req)
3986 {
3987 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003988 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003989 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003990 }
3991
3992 /*
3993 * setting up 0, just in case.
3994 */
3995 req->n_ssids = 0;
3996 req->n_channels = 0;
3997 req->ie = 0;
3998
Jeff Johnson295189b2012-06-20 16:38:30 -07003999 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004000 /* Scan is no longer pending */
4001 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004002
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004003 /*
4004 * cfg80211_scan_done informing NL80211 about completion
4005 * of scanning
4006 */
4007 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004008 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004009
Jeff Johnsone7245742012-09-05 17:12:55 -07004010allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004011 /* release the wake lock at the end of the scan*/
4012 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004013
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004014 /* Acquire wakelock to handle the case where APP's tries to suspend
4015 * immediatly after the driver gets connect request(i.e after scan)
4016 * from supplicant, this result in app's is suspending and not able
4017 * to process the connect request to AP */
4018 hdd_allow_suspend_timeout(100);
4019
Jeff Johnson295189b2012-06-20 16:38:30 -07004020 EXIT();
4021 return 0;
4022}
4023
4024/*
Madan Mohan Koyyalamudi023964b2013-01-11 15:29:03 -08004025 * FUNCTION: hdd_isScanAllowed
4026 * Go through each adapter and check if scan allowed
4027 *
4028 */
4029v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4030{
4031 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4032 hdd_station_ctx_t *pHddStaCtx = NULL;
4033 hdd_adapter_t *pAdapter = NULL;
4034 VOS_STATUS status = 0;
4035 v_U8_t staId = 0;
4036 v_U8_t *staMac = NULL;
4037
4038 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4039
4040 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4041 {
4042 pAdapter = pAdapterNode->pAdapter;
4043
4044 if( pAdapter )
4045 {
4046 hddLog(VOS_TRACE_LEVEL_INFO,
4047 "%s: Adapter with device mode %d exists",
4048 __func__, pAdapter->device_mode);
4049 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4050 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4051 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4052 {
4053 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4054 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4055 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4056 {
4057 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4058 hddLog(VOS_TRACE_LEVEL_ERROR,
4059 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4060 "middle of WPS/EAPOL exchange.", __func__,
4061 staMac[0], staMac[1], staMac[2],
4062 staMac[3], staMac[4], staMac[5]);
4063 return VOS_FALSE;
4064 }
4065 }
4066 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4067 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4068 {
4069 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4070 {
4071 if ((pAdapter->aStaInfo[staId].isUsed) &&
4072 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4073 {
4074 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4075
4076 hddLog(VOS_TRACE_LEVEL_ERROR,
4077 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4078 "middle of WPS/EAPOL exchange.", __func__,
4079 staMac[0], staMac[1], staMac[2],
4080 staMac[3], staMac[4], staMac[5]);
4081 return VOS_FALSE;
4082 }
4083 }
4084 }
4085 }
4086 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4087 pAdapterNode = pNext;
4088 }
4089 hddLog(VOS_TRACE_LEVEL_INFO,
4090 "%s: Scan allowed", __func__);
4091 return VOS_TRUE;
4092}
4093
4094/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004095 * FUNCTION: wlan_hdd_cfg80211_scan
4096 * this scan respond to scan trigger and update cfg80211 scan database
4097 * later, scan dump command can be used to recieve scan results
4098 */
Jeff Johnsoncab8ddc2013-01-18 17:05:29 -08004099int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4100#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4101 struct net_device *dev,
4102#endif
4103 struct cfg80211_scan_request *request)
4104{
4105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4106 struct net_device *dev = request->wdev->netdev;
4107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4109 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4110 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4111 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4112 tCsrScanRequest scanRequest;
4113 tANI_U8 *channelList = NULL, i;
4114 v_U32_t scanId = 0;
4115 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004116 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004117#ifdef WLAN_FEATURE_P2P
4118 v_U8_t* pP2pIe = NULL;
4119#endif
4120
4121 ENTER();
4122
4123 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4124 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004125
4126 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4127 (eConnectionState_Connecting ==
4128 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
4129 {
4130 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi6bd84fa2012-12-03 16:34:04 -08004131 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4132 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004133 return -EBUSY;
4134 }
4135
Jeff Johnson295189b2012-06-20 16:38:30 -07004136#ifdef WLAN_BTAMP_FEATURE
4137 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004138 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07004139 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004140 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004141 "%s: No scanning when AMP is on", __func__);
4142 return -EOPNOTSUPP;
4143 }
4144#endif
4145 //Scan on any other interface is not supported.
4146 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
4147 {
4148 hddLog(VOS_TRACE_LEVEL_ERROR,
4149 "%s: Not scanning on device_mode = %d",
4150 __func__, pAdapter->device_mode);
4151 return -EOPNOTSUPP;
4152 }
4153
4154 if (TRUE == pScanInfo->mScanPending)
4155 {
4156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
4157 return -EBUSY;
4158 }
4159
4160 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4161 {
4162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4163 "%s:LOGP in Progress. Ignore!!!", __func__);
4164 return -EAGAIN;
4165 }
4166
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004167 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4168 {
4169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4170 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4171 return -EAGAIN;
4172 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004173 //Don't Allow Scan and return busy if Remain On
4174 //Channel and action frame is pending
4175 //Otherwise Cancel Remain On Channel and allow Scan
4176 //If no action frame pending
4177 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
4178 {
4179 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4180 return -EBUSY;
4181 }
4182
Jeff Johnson295189b2012-06-20 16:38:30 -07004183 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4184 {
4185 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson3d710ea2012-12-10 14:31:52 -08004186 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004187 return -EAGAIN;
4188 }
4189 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4190 {
4191 hddLog(VOS_TRACE_LEVEL_WARN,
4192 "%s: MAX TM Level Scan not allowed", __func__);
4193 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4194 return -EBUSY;
4195 }
4196 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4197
Madan Mohan Koyyalamudi023964b2013-01-11 15:29:03 -08004198 /* Check if scan is allowed at this point of time.
4199 */
4200 if (!hdd_isScanAllowed(pHddCtx))
4201 {
4202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4203 return -EBUSY;
4204 }
4205
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4207
4208 if (NULL != request)
4209 {
4210 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4211 (int)request->n_ssids);
4212
4213 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4214 * Becasue of this, driver is assuming that this is not wildcard scan and so
4215 * is not aging out the scan results.
4216 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004217 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 {
4219 request->n_ssids = 0;
4220 }
4221
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004222 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 {
4224 tCsrSSIDInfo *SsidInfo;
4225 int j;
4226 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4227 /* Allocate num_ssid tCsrSSIDInfo structure */
4228 SsidInfo = scanRequest.SSIDs.SSIDList =
4229 ( tCsrSSIDInfo *)vos_mem_malloc(
4230 request->n_ssids*sizeof(tCsrSSIDInfo));
4231
4232 if(NULL == scanRequest.SSIDs.SSIDList)
4233 {
4234 hddLog(VOS_TRACE_LEVEL_ERROR,
4235 "memory alloc failed SSIDInfo buffer");
4236 return -ENOMEM;
4237 }
4238
4239 /* copy all the ssid's and their length */
4240 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4241 {
4242 /* get the ssid length */
4243 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4244 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4245 SsidInfo->SSID.length);
4246 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4247 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4248 j, SsidInfo->SSID.ssId);
4249 }
4250 /* set the scan type to active */
4251 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4252 }
4253 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4254 {
4255 /* set the scan type to active */
4256 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4257 }
4258 else
4259 {
4260 /*Set the scan type to default type, in this case it is ACTIVE*/
4261 scanRequest.scanType = pScanInfo->scan_mode;
4262 }
4263 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4264 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4265 }
4266 else
4267 {
4268 /* set the scan type to active */
4269 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4270 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4271
4272 /* set min and max channel time to zero */
4273 scanRequest.minChnTime = 0;
4274 scanRequest.maxChnTime = 0;
4275 }
4276
4277 /* set BSSType to default type */
4278 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4279
4280 /*TODO: scan the requested channels only*/
4281
4282 /*Right now scanning all the channels */
4283 if( request )
4284 {
4285 if( request->n_channels )
4286 {
4287 channelList = vos_mem_malloc( request->n_channels );
4288 if( NULL == channelList )
4289 {
4290 status = -ENOMEM;
4291 goto free_mem;
4292 }
4293
4294 for( i = 0 ; i < request->n_channels ; i++ )
4295 channelList[i] = request->channels[i]->hw_value;
4296 }
4297
4298 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4299 scanRequest.ChannelInfo.ChannelList = channelList;
4300
4301 /* set requestType to full scan */
4302 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004303
4304 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4305 * search (Flush on both full scan and social scan but not on single
4306 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4307 */
4308
4309 /* Supplicant does single channel scan after 8-way handshake
4310 * and in that case driver shoudnt flush scan results. If
4311 * driver flushes the scan results here and unfortunately if
4312 * the AP doesnt respond to our probe req then association
4313 * fails which is not desired
4314 */
4315
4316 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4317 {
4318 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4319 pAdapter->sessionId );
4320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004321
4322 if( request->ie_len )
4323 {
4324 /* save this for future association (join requires this) */
4325 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4326 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4327 pScanInfo->scanAddIE.length = request->ie_len;
4328
4329 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004330 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4331 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004332 )
4333 {
4334 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4335 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4336 }
4337
4338 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4339 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4340
4341#ifdef WLAN_FEATURE_P2P
4342 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4343 request->ie_len);
4344 if (pP2pIe != NULL)
4345 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004346#ifdef WLAN_FEATURE_P2P_DEBUG
4347 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4348 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4349 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4350 {
4351 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4352 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4353 "Go nego completed to Connection is started");
4354 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4355 "for 8way Handshake");
4356 }
4357 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4358 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4359 {
4360 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4361 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4362 "Disconnected state to Connection is started");
4363 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4364 "for 4way Handshake");
4365 }
4366#endif
4367
Jeff Johnsone7245742012-09-05 17:12:55 -07004368 /* no_cck will be set during p2p find to disable 11b rates */
4369 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004370 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004371 hddLog(VOS_TRACE_LEVEL_INFO,
4372 "%s: This is a P2P Search", __func__);
4373 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004374
Jeff Johnsone7245742012-09-05 17:12:55 -07004375 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4376 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004377 /* set requestType to P2P Discovery */
4378 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004379 }
4380
4381 /*
4382 Skip Dfs Channel in case of P2P Search
4383 if it is set in ini file
4384 */
4385 if(cfg_param->skipDfsChnlInP2pSearch)
4386 {
4387 scanRequest.skipDfsChnlInP2pSearch = 1;
4388 }
4389 else
4390 {
4391 scanRequest.skipDfsChnlInP2pSearch = 0;
4392 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004393
Jeff Johnson295189b2012-06-20 16:38:30 -07004394 }
4395 }
4396#endif
4397 }
4398 }
4399
4400 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4401
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004402 /* acquire the wakelock to avoid the apps suspend during the scan. To
4403 * address the following issues.
4404 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4405 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4406 * for long time, this result in apps running at full power for long time.
4407 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4408 * be stuck in full power because of resume BMPS
4409 */
4410 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004411
4412 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004413 pAdapter->sessionId, &scanRequest, &scanId,
4414 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004415
Jeff Johnson295189b2012-06-20 16:38:30 -07004416 if (eHAL_STATUS_SUCCESS != status)
4417 {
4418 hddLog(VOS_TRACE_LEVEL_ERROR,
4419 "%s: sme_ScanRequest returned error %d", __func__, status);
4420 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004421 if(eHAL_STATUS_RESOURCES == status)
4422 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004423 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 -07004424 status = -EBUSY;
4425 } else {
4426 status = -EIO;
4427 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004428 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004429 goto free_mem;
4430 }
4431
4432 pScanInfo->mScanPending = TRUE;
4433 pAdapter->request = request;
4434 pScanInfo->scanId = scanId;
4435
4436 complete(&pScanInfo->scan_req_completion_event);
4437
4438free_mem:
4439 if( scanRequest.SSIDs.SSIDList )
4440 {
4441 vos_mem_free(scanRequest.SSIDs.SSIDList);
4442 }
4443
4444 if( channelList )
4445 vos_mem_free( channelList );
4446
4447 EXIT();
4448
4449 return status;
4450}
4451
4452/*
4453 * FUNCTION: wlan_hdd_cfg80211_connect_start
4454 * This function is used to start the association process
4455 */
4456int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004457 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004458{
4459 int status = 0;
4460 hdd_wext_state_t *pWextState;
4461 v_U32_t roamId;
4462 tCsrRoamProfile *pRoamProfile;
4463 eMib_dot11DesiredBssType connectedBssType;
4464 eCsrAuthType RSNAuthType;
4465
4466 ENTER();
4467
4468 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4469
4470 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4471 {
4472 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4473 return -EINVAL;
4474 }
4475
4476 pRoamProfile = &pWextState->roamProfile;
4477
4478 if (pRoamProfile)
4479 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004480 int ret = 0;
4481 hdd_station_ctx_t *pHddStaCtx;
4482 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4483 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4484
4485 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4486 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4487 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 {
4489 /* Issue disconnect to CSR */
4490 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4491 if( eHAL_STATUS_SUCCESS ==
4492 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4493 pAdapter->sessionId,
4494 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4495 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004496 ret = wait_for_completion_interruptible_timeout(
4497 &pAdapter->disconnect_comp_var,
4498 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4499 if (0 == ret)
4500 {
4501 VOS_ASSERT(0);
4502 }
4503 }
4504 }
4505 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4506 {
4507 ret = wait_for_completion_interruptible_timeout(
4508 &pAdapter->disconnect_comp_var,
4509 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4510 if (0 == ret)
4511 {
4512 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004513 }
4514 }
4515
4516 if (HDD_WMM_USER_MODE_NO_QOS ==
4517 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4518 {
4519 /*QoS not enabled in cfg file*/
4520 pRoamProfile->uapsd_mask = 0;
4521 }
4522 else
4523 {
4524 /*QoS enabled, update uapsd mask from cfg file*/
4525 pRoamProfile->uapsd_mask =
4526 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4527 }
4528
4529 pRoamProfile->SSIDs.numOfSSIDs = 1;
4530 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4531 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4532 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4533 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4534 ssid, ssid_len);
4535
4536 if (bssid)
4537 {
4538 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4539 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4540 WNI_CFG_BSSID_LEN);
4541 /* Save BSSID in seperate variable as well, as RoamProfile
4542 BSSID is getting zeroed out in the association process. And in
4543 case of join failure we should send valid BSSID to supplicant
4544 */
4545 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4546 WNI_CFG_BSSID_LEN);
4547 }
4548
4549 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4550 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4551 {
4552 /*set gen ie*/
4553 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4554 /*set auth*/
4555 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4556 }
4557 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4558 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4559 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4560 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4561 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4562 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4563 )
4564 {
4565 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4566 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4567 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4568 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4569 eCSR_AUTH_TYPE_AUTOSWITCH;
4570 pWextState->roamProfile.AuthType.authType[0] =
4571 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4572 }
4573#ifdef FEATURE_WLAN_WAPI
4574 if (pAdapter->wapi_info.nWapiMode)
4575 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004576 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004577 switch (pAdapter->wapi_info.wapiAuthMode)
4578 {
4579 case WAPI_AUTH_MODE_PSK:
4580 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004581 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004582 pAdapter->wapi_info.wapiAuthMode);
4583 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4584 break;
4585 }
4586 case WAPI_AUTH_MODE_CERT:
4587 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004588 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004589 pAdapter->wapi_info.wapiAuthMode);
4590 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4591 break;
4592 }
4593 } // End of switch
4594 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4595 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4596 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004597 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004598 pRoamProfile->AuthType.numEntries = 1;
4599 pRoamProfile->EncryptionType.numEntries = 1;
4600 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4601 pRoamProfile->mcEncryptionType.numEntries = 1;
4602 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4603 }
4604 }
4605#endif /* FEATURE_WLAN_WAPI */
4606 pRoamProfile->csrPersona = pAdapter->device_mode;
4607
Jeff Johnson32d95a32012-09-10 13:15:23 -07004608 if( operatingChannel )
4609 {
4610 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4611 pRoamProfile->ChannelInfo.numOfChannels = 1;
4612 }
4613
Madan Mohan Koyyalamudi6bd84fa2012-12-03 16:34:04 -08004614 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4615 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4616 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4617 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudif357acc2012-12-04 17:03:44 -08004618 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4619 */
4620 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4621 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4622 eConnectionState_Connecting);
Madan Mohan Koyyalamudi6bd84fa2012-12-03 16:34:04 -08004623
Jeff Johnson295189b2012-06-20 16:38:30 -07004624 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4625 pAdapter->sessionId, pRoamProfile, &roamId);
4626
Madan Mohan Koyyalamudi6bd84fa2012-12-03 16:34:04 -08004627 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304628 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4629
4630 {
Madan Mohan Koyyalamudi6bd84fa2012-12-03 16:34:04 -08004631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4632 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4633 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304634 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi6bd84fa2012-12-03 16:34:04 -08004635 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304636 }
Madan Mohan Koyyalamudif357acc2012-12-04 17:03:44 -08004637
4638 pRoamProfile->ChannelInfo.ChannelList = NULL;
4639 pRoamProfile->ChannelInfo.numOfChannels = 0;
4640
Jeff Johnson295189b2012-06-20 16:38:30 -07004641 }
4642 else
4643 {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4645 return -EINVAL;
4646 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004647 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 return status;
4649}
4650
4651/*
4652 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4653 * This function is used to set the authentication type (OPEN/SHARED).
4654 *
4655 */
4656static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4657 enum nl80211_auth_type auth_type)
4658{
4659 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4660 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4661
4662 ENTER();
4663
4664 /*set authentication type*/
4665 switch (auth_type)
4666 {
4667 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4668 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004669#ifdef WLAN_FEATURE_VOWIFI_11R
4670 case NL80211_AUTHTYPE_FT:
4671#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004672 hddLog(VOS_TRACE_LEVEL_INFO,
4673 "%s: set authentication type to OPEN", __func__);
4674 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4675 break;
4676
4677 case NL80211_AUTHTYPE_SHARED_KEY:
4678 hddLog(VOS_TRACE_LEVEL_INFO,
4679 "%s: set authentication type to SHARED", __func__);
4680 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4681 break;
4682#ifdef FEATURE_WLAN_CCX
4683 case NL80211_AUTHTYPE_NETWORK_EAP:
4684 hddLog(VOS_TRACE_LEVEL_INFO,
4685 "%s: set authentication type to CCKM WPA", __func__);
4686 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4687 break;
4688#endif
4689
4690
4691 default:
4692 hddLog(VOS_TRACE_LEVEL_ERROR,
4693 "%s: Unsupported authentication type %d", __func__,
4694 auth_type);
4695 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4696 return -EINVAL;
4697 }
4698
4699 pWextState->roamProfile.AuthType.authType[0] =
4700 pHddStaCtx->conn_info.authType;
4701 return 0;
4702}
4703
4704/*
4705 * FUNCTION: wlan_hdd_set_akm_suite
4706 * This function is used to set the key mgmt type(PSK/8021x).
4707 *
4708 */
4709static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4710 u32 key_mgmt
4711 )
4712{
4713 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4714 ENTER();
4715
4716 /*set key mgmt type*/
4717 switch(key_mgmt)
4718 {
4719 case WLAN_AKM_SUITE_PSK:
4720 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4721 __func__);
4722 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4723 break;
4724
4725 case WLAN_AKM_SUITE_8021X:
4726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4727 __func__);
4728 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4729 break;
4730#ifdef FEATURE_WLAN_CCX
4731#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4732#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4733 case WLAN_AKM_SUITE_CCKM:
4734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4735 __func__);
4736 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4737 break;
4738#endif
4739
4740 default:
4741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4742 __func__, key_mgmt);
4743 return -EINVAL;
4744
4745 }
4746 return 0;
4747}
4748
4749/*
4750 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4751 * This function is used to set the encryption type
4752 * (NONE/WEP40/WEP104/TKIP/CCMP).
4753 */
4754static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4755 u32 cipher,
4756 bool ucast
4757 )
4758{
4759 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4760 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4761 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4762
4763 ENTER();
4764
4765 if (!cipher)
4766 {
4767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4768 __func__, cipher);
4769 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4770 }
4771 else
4772 {
4773
4774 /*set encryption method*/
4775 switch (cipher)
4776 {
4777 case IW_AUTH_CIPHER_NONE:
4778 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4779 break;
4780
4781 case WLAN_CIPHER_SUITE_WEP40:
4782 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4783 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4784 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4785 else
4786 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4787 break;
4788
4789 case WLAN_CIPHER_SUITE_WEP104:
4790 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4791 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4792 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4793 else
4794 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4795 break;
4796
4797 case WLAN_CIPHER_SUITE_TKIP:
4798 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4799 break;
4800
4801 case WLAN_CIPHER_SUITE_CCMP:
4802 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4803 break;
4804#ifdef FEATURE_WLAN_WAPI
4805 case WLAN_CIPHER_SUITE_SMS4:
4806 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4807 break;
4808#endif
4809
4810#ifdef FEATURE_WLAN_CCX
4811 case WLAN_CIPHER_SUITE_KRK:
4812 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4813 break;
4814#endif
4815 default:
4816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4817 __func__, cipher);
4818 return -EOPNOTSUPP;
4819 }
4820 }
4821
4822 if (ucast)
4823 {
4824 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4825 __func__, encryptionType);
4826 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4827 pWextState->roamProfile.EncryptionType.numEntries = 1;
4828 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4829 encryptionType;
4830 }
4831 else
4832 {
4833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4834 __func__, encryptionType);
4835 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4836 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4837 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4838 }
4839
4840 return 0;
4841}
4842
4843
4844/*
4845 * FUNCTION: wlan_hdd_cfg80211_set_ie
4846 * This function is used to parse WPA/RSN IE's.
4847 */
4848int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4849 u8 *ie,
4850 size_t ie_len
4851 )
4852{
4853 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4854 u8 *genie = ie;
4855 v_U16_t remLen = ie_len;
4856#ifdef FEATURE_WLAN_WAPI
4857 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4858 u16 *tmp;
4859 v_U16_t akmsuiteCount;
4860 int *akmlist;
4861#endif
4862 ENTER();
4863
4864 /* clear previous assocAddIE */
4865 pWextState->assocAddIE.length = 0;
4866 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4867
4868 while (remLen >= 2)
4869 {
4870 v_U16_t eLen = 0;
4871 v_U8_t elementId;
4872 elementId = *genie++;
4873 eLen = *genie++;
4874 remLen -= 2;
4875
4876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4877 __func__, elementId, eLen);
4878
4879 switch ( elementId )
4880 {
4881 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004882 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 -07004883 {
4884 hddLog(VOS_TRACE_LEVEL_ERROR,
4885 "%s: Invalid WPA IE", __func__);
4886 return -EINVAL;
4887 }
4888 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4889 {
4890 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4891 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4892 __func__, eLen + 2);
4893
4894 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4895 {
Jeff Johnson1920a722012-12-10 14:28:09 -08004896 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4897 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004898 VOS_ASSERT(0);
4899 return -ENOMEM;
4900 }
4901 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4902 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4903 pWextState->assocAddIE.length += eLen + 2;
4904
4905 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4906 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4907 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4908 }
4909 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4910 {
4911 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4912 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4913 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4914 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4915 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4916 }
4917#ifdef WLAN_FEATURE_P2P
4918 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4919 P2P_OUI_TYPE_SIZE))
4920 /*Consider P2P IE, only for P2P Client */
4921 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4922 {
4923 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4924 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4925 __func__, eLen + 2);
4926
4927 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4928 {
Jeff Johnson1920a722012-12-10 14:28:09 -08004929 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4930 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004931 VOS_ASSERT(0);
4932 return -ENOMEM;
4933 }
4934 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4935 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4936 pWextState->assocAddIE.length += eLen + 2;
4937
4938 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4939 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4940 }
4941#endif
4942#ifdef WLAN_FEATURE_WFD
4943 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4944 WFD_OUI_TYPE_SIZE))
4945 /*Consider WFD IE, only for P2P Client */
4946 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4947 {
4948 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4949 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4950 __func__, eLen + 2);
4951
4952 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4953 {
Jeff Johnson1920a722012-12-10 14:28:09 -08004954 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4955 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 VOS_ASSERT(0);
4957 return -ENOMEM;
4958 }
4959 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4960 // WPS IE + P2P IE + WFD IE
4961 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4962 pWextState->assocAddIE.length += eLen + 2;
4963
4964 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4965 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4966 }
4967#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004968 /* Appending HS 2.0 Indication Element in Assiciation Request */
4969 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004970 HS20_OUI_TYPE_SIZE)) )
4971 {
4972 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4973 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4974 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004975
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004976 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4977 {
Jeff Johnson1920a722012-12-10 14:28:09 -08004978 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4979 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004980 VOS_ASSERT(0);
4981 return -ENOMEM;
4982 }
4983 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4984 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004985
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004986 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4987 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4988 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004989
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 break;
4991 case DOT11F_EID_RSN:
4992 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4993 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4994 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4995 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4996 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4997 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004998 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
4999 case DOT11F_EID_EXTCAP:
5000 {
5001 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5002 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5003 __func__, eLen + 2);
5004
5005 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5006 {
Jeff Johnson1920a722012-12-10 14:28:09 -08005007 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5008 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005009 VOS_ASSERT(0);
5010 return -ENOMEM;
5011 }
5012 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5013 pWextState->assocAddIE.length += eLen + 2;
5014
5015 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5016 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5017 break;
5018 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005019#ifdef FEATURE_WLAN_WAPI
5020 case WLAN_EID_WAPI:
5021 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5022 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5023 pAdapter->wapi_info.nWapiMode);
5024 tmp = (u16 *)ie;
5025 tmp = tmp + 2; // Skip element Id and Len, Version
5026 akmsuiteCount = WPA_GET_LE16(tmp);
5027 tmp = tmp + 1;
5028 akmlist = (int *)(tmp);
5029 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5030 {
5031 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5032 }
5033 else
5034 {
5035 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5036 VOS_ASSERT(0);
5037 return -EINVAL;
5038 }
5039
5040 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5041 {
5042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005043 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005044 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5045 }
5046 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5047 {
5048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005049 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5051 }
5052 break;
5053#endif
5054 default:
5055 hddLog (VOS_TRACE_LEVEL_ERROR,
5056 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005057 /* when Unknown IE is received we should break and continue
5058 * to the next IE in the buffer instead we were returning
5059 * so changing this to break */
5060 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005061 }
5062 genie += eLen;
5063 remLen -= eLen;
5064 }
5065 EXIT();
5066 return 0;
5067}
5068
5069/*
5070 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5071 * This function is used to initialize the security
5072 * parameters during connect operation.
5073 */
5074int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5075 struct cfg80211_connect_params *req
5076 )
5077{
5078 int status = 0;
5079 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5080 ENTER();
5081
5082 /*set wpa version*/
5083 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5084
5085 if (req->crypto.wpa_versions)
5086 {
5087 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5088 && ( (req->ie_len)
5089 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5090 // Make sure that it is including a WPA IE.
5091 /* Currently NL is putting WPA version 1 even for open,
5092 * since p2p ie is also put in same buffer.
5093 * */
5094 {
5095 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5096 }
5097 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5098 {
5099 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5100 }
5101 }
5102
5103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5104 pWextState->wpaVersion);
5105
5106 /*set authentication type*/
5107 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5108
5109 if (0 > status)
5110 {
5111 hddLog(VOS_TRACE_LEVEL_ERROR,
5112 "%s: failed to set authentication type ", __func__);
5113 return status;
5114 }
5115
5116 /*set key mgmt type*/
5117 if (req->crypto.n_akm_suites)
5118 {
5119 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5120 if (0 > status)
5121 {
5122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5123 __func__);
5124 return status;
5125 }
5126 }
5127
5128 /*set pairwise cipher type*/
5129 if (req->crypto.n_ciphers_pairwise)
5130 {
5131 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5132 req->crypto.ciphers_pairwise[0], true);
5133 if (0 > status)
5134 {
5135 hddLog(VOS_TRACE_LEVEL_ERROR,
5136 "%s: failed to set unicast cipher type", __func__);
5137 return status;
5138 }
5139 }
5140 else
5141 {
5142 /*Reset previous cipher suite to none*/
5143 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5144 if (0 > status)
5145 {
5146 hddLog(VOS_TRACE_LEVEL_ERROR,
5147 "%s: failed to set unicast cipher type", __func__);
5148 return status;
5149 }
5150 }
5151
5152 /*set group cipher type*/
5153 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5154 false);
5155
5156 if (0 > status)
5157 {
5158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5159 __func__);
5160 return status;
5161 }
5162
5163 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5164 if (req->ie_len)
5165 {
5166 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5167 if ( 0 > status)
5168 {
5169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5170 __func__);
5171 return status;
5172 }
5173 }
5174
5175 /*incase of WEP set default key information*/
5176 if (req->key && req->key_len)
5177 {
5178 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5179 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5180 )
5181 {
5182 if ( IW_AUTH_KEY_MGMT_802_1X
5183 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5184 {
5185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5186 __func__);
5187 return -EOPNOTSUPP;
5188 }
5189 else
5190 {
5191 u8 key_len = req->key_len;
5192 u8 key_idx = req->key_idx;
5193
5194 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5195 && (CSR_MAX_NUM_KEY > key_idx)
5196 )
5197 {
5198 hddLog(VOS_TRACE_LEVEL_INFO,
5199 "%s: setting default wep key, key_idx = %hu key_len %hu",
5200 __func__, key_idx, key_len);
5201 vos_mem_copy(
5202 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5203 req->key, key_len);
5204 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5205 (u8)key_len;
5206 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5207 }
5208 }
5209 }
5210 }
5211
5212 return status;
5213}
5214
5215/*
5216 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5217 * This function is used to initialize the security
5218 * parameters during connect operation.
5219 */
5220static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5221 struct net_device *ndev,
5222 struct cfg80211_connect_params *req
5223 )
5224{
5225 int status = 0;
5226 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5227 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5228 hdd_context_t *pHddCtx = NULL;
5229
5230 ENTER();
5231
5232 hddLog(VOS_TRACE_LEVEL_INFO,
5233 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5234
5235 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5236 {
5237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5238 "%s:LOGP in Progress. Ignore!!!", __func__);
5239 return -EAGAIN;
5240 }
5241
5242#ifdef WLAN_BTAMP_FEATURE
5243 //Infra connect not supported when AMP traffic is on.
5244 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5245 {
5246 hddLog(VOS_TRACE_LEVEL_ERROR,
5247 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005248 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 }
5250#endif
5251 /*initialise security parameters*/
5252 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5253
5254 if ( 0 > status)
5255 {
5256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5257 __func__);
5258 return status;
5259 }
5260
5261 //If Device Mode is Station Concurrent Sessions Exit BMps
Madan Mohan Koyyalamudic1275fc2012-12-12 16:49:33 -08005262 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5264 (vos_concurrent_sessions_running()))
5265 {
5266 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5267
5268 if (NULL != pVosContext)
5269 {
5270 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5271 if(NULL != pHddCtx)
5272 {
5273 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5274 }
5275 }
5276 }
5277
Mohit Khanna765234a2012-09-11 15:08:35 -07005278 if ( req->channel )
5279 {
5280 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5281 req->ssid_len, req->bssid,
5282 req->channel->hw_value);
5283 }
5284 else
5285 {
5286 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5287 req->ssid_len, req->bssid,
5288 0);
5289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005290
5291 if (0 > status)
5292 {
5293 //ReEnable BMPS if disabled
5294 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5295 (NULL != pHddCtx))
5296 {
5297 //ReEnable Bmps and Imps back
5298 hdd_enable_bmps_imps(pHddCtx);
5299 }
5300
5301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5302 return status;
5303 }
5304 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5305 EXIT();
5306 return status;
5307}
5308
5309
5310/*
5311 * FUNCTION: wlan_hdd_cfg80211_disconnect
5312 * This function is used to issue a disconnect request to SME
5313 */
5314static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5315 struct net_device *dev,
5316 u16 reason
5317 )
5318{
5319 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5320 tCsrRoamProfile *pRoamProfile =
5321 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5322 int status = 0;
5323 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5324
5325 ENTER();
5326
5327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5328 __func__,pAdapter->device_mode);
5329
5330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5331 __func__, reason);
5332
5333 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5334 {
5335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5336 "%s:LOGP in Progress. Ignore!!!",__func__);
5337 return -EAGAIN;
5338 }
5339 if (NULL != pRoamProfile)
5340 {
5341 /*issue disconnect request to SME, if station is in connected state*/
5342 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5343 {
5344 eCsrRoamDisconnectReason reasonCode =
5345 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5346 switch(reason)
5347 {
5348 case WLAN_REASON_MIC_FAILURE:
5349 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5350 break;
5351
5352 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5353 case WLAN_REASON_DISASSOC_AP_BUSY:
5354 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5355 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5356 break;
5357
5358 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5359 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5360 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5361 break;
5362
5363 case WLAN_REASON_DEAUTH_LEAVING:
5364 default:
5365 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5366 break;
5367 }
5368 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5369 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5370 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5371
5372 /*issue disconnect*/
5373 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5374 pAdapter->sessionId, reasonCode);
5375
5376 if ( 0 != status)
5377 {
5378 hddLog(VOS_TRACE_LEVEL_ERROR,
5379 "%s csrRoamDisconnect failure, returned %d \n",
5380 __func__, (int)status );
5381 return -EINVAL;
5382 }
5383
5384 wait_for_completion_interruptible_timeout(
5385 &pAdapter->disconnect_comp_var,
5386 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5387
5388
5389 /*stop tx queues*/
5390 netif_tx_disable(dev);
5391 netif_carrier_off(dev);
5392 }
5393 }
5394 else
5395 {
5396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5397 }
5398
5399 return status;
5400}
5401
5402/*
5403 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5404 * This function is used to initialize the security
5405 * settings in IBSS mode.
5406 */
5407static int wlan_hdd_cfg80211_set_privacy_ibss(
5408 hdd_adapter_t *pAdapter,
5409 struct cfg80211_ibss_params *params
5410 )
5411{
5412 int status = 0;
5413 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5414 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5415 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5416
5417 ENTER();
5418
5419 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5420
5421 if (params->ie_len && ( NULL != params->ie) )
5422 {
5423 if (WLAN_EID_RSN == params->ie[0])
5424 {
5425 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5426 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5427 }
5428 else
5429 {
5430 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5431 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5432 }
5433 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5434
5435 if (0 > status)
5436 {
5437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5438 __func__);
5439 return status;
5440 }
5441 }
5442
5443 pWextState->roamProfile.AuthType.authType[0] =
5444 pHddStaCtx->conn_info.authType =
5445 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5446
5447 if (params->privacy)
5448 {
5449 /* Security enabled IBSS, At this time there is no information available
5450 * about the security paramters, so initialise the encryption type to
5451 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5452 * The correct security parameters will be updated later in
5453 * wlan_hdd_cfg80211_add_key */
5454 /* Hal expects encryption type to be set inorder
5455 *enable privacy bit in beacons */
5456
5457 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5458 }
5459
5460 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5461 pWextState->roamProfile.EncryptionType.numEntries = 1;
5462 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5463
5464 return status;
5465}
5466
5467/*
5468 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5469 * This function is used to create/join an IBSS
5470 */
5471static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5472 struct net_device *dev,
5473 struct cfg80211_ibss_params *params
5474 )
5475{
5476 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5477 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5478 tCsrRoamProfile *pRoamProfile;
5479 int status;
5480 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5481
5482 ENTER();
5483
5484 hddLog(VOS_TRACE_LEVEL_INFO,
5485 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5486
5487 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5488 {
5489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5490 "%s:LOGP in Progress. Ignore!!!", __func__);
5491 return -EAGAIN;
5492 }
5493
5494 if (NULL == pWextState)
5495 {
5496 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5497 __func__);
5498 return -EIO;
5499 }
5500
5501 pRoamProfile = &pWextState->roamProfile;
5502
5503 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5504 {
5505 hddLog (VOS_TRACE_LEVEL_ERROR,
5506 "%s Interface type is not set to IBSS \n", __func__);
5507 return -EINVAL;
5508 }
5509
5510 /* Set Channel */
5511 if (NULL != params->channel)
5512 {
5513 u8 channelNum;
5514 if (IEEE80211_BAND_5GHZ == params->channel->band)
5515 {
5516 hddLog(VOS_TRACE_LEVEL_ERROR,
5517 "%s: IBSS join is called with unsupported band %d",
5518 __func__, params->channel->band);
5519 return -EOPNOTSUPP;
5520 }
5521
5522 /* Get channel number */
5523 channelNum =
5524 ieee80211_frequency_to_channel(params->channel->center_freq);
5525
5526 /*TODO: use macro*/
5527 if (14 >= channelNum)
5528 {
5529 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5530 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5531 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5532 int indx;
5533
5534 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5535 validChan, &numChans))
5536 {
5537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5538 __func__);
5539 return -EOPNOTSUPP;
5540 }
5541
5542 for (indx = 0; indx < numChans; indx++)
5543 {
5544 if (channelNum == validChan[indx])
5545 {
5546 break;
5547 }
5548 }
5549 if (indx >= numChans)
5550 {
5551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5552 __func__, channelNum);
5553 return -EINVAL;
5554 }
5555 /* Set the Operational Channel */
5556 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5557 channelNum);
5558 pRoamProfile->ChannelInfo.numOfChannels = 1;
5559 pHddStaCtx->conn_info.operationChannel = channelNum;
5560 pRoamProfile->ChannelInfo.ChannelList =
5561 &pHddStaCtx->conn_info.operationChannel;
5562 }
5563 else
5564 {
5565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5566 __func__, channelNum);
5567 return -EINVAL;
5568 }
5569 }
5570
5571 /* Initialize security parameters */
5572 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5573 if (status < 0)
5574 {
5575 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5576 __func__);
5577 return status;
5578 }
5579
5580 /* Issue connect start */
5581 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005582 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005583
5584 if (0 > status)
5585 {
5586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5587 return status;
5588 }
5589
5590 return 0;
5591}
5592
5593/*
5594 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5595 * This function is used to leave an IBSS
5596 */
5597static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5598 struct net_device *dev
5599 )
5600{
5601 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5602 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5603 tCsrRoamProfile *pRoamProfile;
5604
5605 ENTER();
5606
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005607 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5608 {
5609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5610 "%s:LOGP in Progress. Ignore!!!", __func__);
5611 return -EAGAIN;
5612 }
5613
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5615 if (NULL == pWextState)
5616 {
5617 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5618 __func__);
5619 return -EIO;
5620 }
5621
5622 pRoamProfile = &pWextState->roamProfile;
5623
5624 /* Issue disconnect only if interface type is set to IBSS */
5625 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5626 {
5627 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5628 __func__);
5629 return -EINVAL;
5630 }
5631
5632 /* Issue Disconnect request */
5633 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5634 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5635 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5636
5637 return 0;
5638}
5639
5640/*
5641 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5642 * This function is used to set the phy parameters
5643 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5644 */
5645static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5646 u32 changed)
5647{
5648 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5649 tHalHandle hHal = pHddCtx->hHal;
5650
5651 ENTER();
5652
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005653 if ( pHddCtx->isLogpInProgress )
5654 {
5655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5656 "%s:LOGP in Progress. Ignore!!!", __func__);
5657 return -EAGAIN;
5658 }
5659
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5661 {
5662 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5663 WNI_CFG_RTS_THRESHOLD_STAMAX :
5664 wiphy->rts_threshold;
5665
5666 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5667 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5668 {
5669 hddLog(VOS_TRACE_LEVEL_ERROR,
5670 "%s: Invalid RTS Threshold value %hu",
5671 __func__, rts_threshold);
5672 return -EINVAL;
5673 }
5674
5675 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5676 rts_threshold, ccmCfgSetCallback,
5677 eANI_BOOLEAN_TRUE))
5678 {
5679 hddLog(VOS_TRACE_LEVEL_ERROR,
5680 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5681 __func__, rts_threshold);
5682 return -EIO;
5683 }
5684
5685 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5686 rts_threshold);
5687 }
5688
5689 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5690 {
5691 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5692 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5693 wiphy->frag_threshold;
5694
5695 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5696 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5697 {
5698 hddLog(VOS_TRACE_LEVEL_ERROR,
5699 "%s: Invalid frag_threshold value %hu", __func__,
5700 frag_threshold);
5701 return -EINVAL;
5702 }
5703
5704 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5705 frag_threshold, ccmCfgSetCallback,
5706 eANI_BOOLEAN_TRUE))
5707 {
5708 hddLog(VOS_TRACE_LEVEL_ERROR,
5709 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5710 __func__, frag_threshold);
5711 return -EIO;
5712 }
5713
5714 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5715 frag_threshold);
5716 }
5717
5718 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5719 || (changed & WIPHY_PARAM_RETRY_LONG))
5720 {
5721 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5722 wiphy->retry_short :
5723 wiphy->retry_long;
5724
5725 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5726 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5727 {
5728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5729 __func__, retry_value);
5730 return -EINVAL;
5731 }
5732
5733 if (changed & WIPHY_PARAM_RETRY_SHORT)
5734 {
5735 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5736 retry_value, ccmCfgSetCallback,
5737 eANI_BOOLEAN_TRUE))
5738 {
5739 hddLog(VOS_TRACE_LEVEL_ERROR,
5740 "%s: ccmCfgSetInt failed for long retry count %hu",
5741 __func__, retry_value);
5742 return -EIO;
5743 }
5744 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5745 __func__, retry_value);
5746 }
5747 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5748 {
5749 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5750 retry_value, ccmCfgSetCallback,
5751 eANI_BOOLEAN_TRUE))
5752 {
5753 hddLog(VOS_TRACE_LEVEL_ERROR,
5754 "%s: ccmCfgSetInt failed for short retry count %hu",
5755 __func__, retry_value);
5756 return -EIO;
5757 }
5758 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5759 __func__, retry_value);
5760 }
5761 }
5762
5763 return 0;
5764}
5765
5766/*
5767 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5768 * This function is used to set the txpower
5769 */
5770static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5771#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5772 enum tx_power_setting type,
5773#else
5774 enum nl80211_tx_power_setting type,
5775#endif
5776 int dbm)
5777{
5778 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5779 tHalHandle hHal = pHddCtx->hHal;
5780 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5781 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5782
5783 ENTER();
5784
5785 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5786 dbm, ccmCfgSetCallback,
5787 eANI_BOOLEAN_TRUE))
5788 {
5789 hddLog(VOS_TRACE_LEVEL_ERROR,
5790 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5791 return -EIO;
5792 }
5793
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005794 if ( pHddCtx->isLogpInProgress )
5795 {
5796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5797 "%s:LOGP in Progress. Ignore!!!", __func__);
5798 return -EAGAIN;
5799 }
5800
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5802 dbm);
5803
5804 switch(type)
5805 {
5806 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5807 /* Fall through */
5808 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5809 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5810 {
5811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5812 __func__);
5813 return -EIO;
5814 }
5815 break;
5816 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5818 __func__);
5819 return -EOPNOTSUPP;
5820 break;
5821 default:
5822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5823 __func__, type);
5824 return -EIO;
5825 }
5826
5827 return 0;
5828}
5829
5830/*
5831 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5832 * This function is used to read the txpower
5833 */
5834static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5835{
5836
5837 hdd_adapter_t *pAdapter;
5838 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5839
Jeff Johnsone7245742012-09-05 17:12:55 -07005840 ENTER();
5841
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 if (NULL == pHddCtx)
5843 {
5844 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5845 *dbm = 0;
5846 return -ENOENT;
5847 }
5848
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005849 if ( pHddCtx->isLogpInProgress )
5850 {
5851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5852 "%s:LOGP in Progress. Ignore!!!", __func__);
5853 return -EAGAIN;
5854 }
5855
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5857 if (NULL == pAdapter)
5858 {
5859 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5860 return -ENOENT;
5861 }
5862
5863 wlan_hdd_get_classAstats(pAdapter);
5864 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5865
Jeff Johnsone7245742012-09-05 17:12:55 -07005866 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 return 0;
5868}
5869
5870static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5871 u8* mac, struct station_info *sinfo)
5872{
5873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5874 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5875 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5876 tANI_U8 rate_flags;
5877
5878 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5879 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5880 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5881
5882 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5883 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5884 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5885 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5886 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5887 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5888 tANI_U16 maxRate = 0;
5889 tANI_U16 myRate;
5890 tANI_U16 currentRate = 0;
5891 tANI_U8 maxSpeedMCS = 0;
5892 tANI_U8 maxMCSIdx = 0;
5893 tANI_U8 rateFlag = 1;
5894 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005895 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005896
Jeff Johnsone7245742012-09-05 17:12:55 -07005897 ENTER();
5898
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5900 (0 == ssidlen))
5901 {
5902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5903 " Invalid ssidlen, %d", __func__, ssidlen);
5904 /*To keep GUI happy*/
5905 return 0;
5906 }
5907
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005908 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5909 {
5910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5911 "%s:LOGP in Progress. Ignore!!!", __func__);
5912 return -EAGAIN;
5913 }
5914
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5916 sinfo->filled |= STATION_INFO_SIGNAL;
5917
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005918 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5920
5921 //convert to the UI units of 100kbps
5922 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5923
5924#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005925 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 -07005926 sinfo->signal,
5927 pCfg->reportMaxLinkSpeed,
5928 myRate,
5929 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005930 (int) pCfg->linkSpeedRssiMid,
5931 (int) pCfg->linkSpeedRssiLow,
5932 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005933#endif //LINKSPEED_DEBUG_ENABLED
5934
5935 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5936 {
5937 // we do not want to necessarily report the current speed
5938 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5939 {
5940 // report the max possible speed
5941 rssidx = 0;
5942 }
5943 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5944 {
5945 // report the max possible speed with RSSI scaling
5946 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5947 {
5948 // report the max possible speed
5949 rssidx = 0;
5950 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005951 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 {
5953 // report middle speed
5954 rssidx = 1;
5955 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005956 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5957 {
5958 // report middle speed
5959 rssidx = 2;
5960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 else
5962 {
5963 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005964 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 }
5966 }
5967 else
5968 {
5969 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5970 hddLog(VOS_TRACE_LEVEL_ERROR,
5971 "%s: Invalid value for reportMaxLinkSpeed: %u",
5972 __func__, pCfg->reportMaxLinkSpeed);
5973 rssidx = 0;
5974 }
5975
5976 maxRate = 0;
5977
5978 /* Get Basic Rate Set */
5979 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5980 for (i = 0; i < ORLeng; i++)
5981 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005982 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 {
5984 /* Validate Rate Set */
5985 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5986 {
5987 currentRate = supported_data_rate[j].supported_rate[rssidx];
5988 break;
5989 }
5990 }
5991 /* Update MAX rate */
5992 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5993 }
5994
5995 /* Get Extended Rate Set */
5996 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5997 for (i = 0; i < ERLeng; i++)
5998 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005999 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 {
6001 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6002 {
6003 currentRate = supported_data_rate[j].supported_rate[rssidx];
6004 break;
6005 }
6006 }
6007 /* Update MAX rate */
6008 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6009 }
6010
6011 /* Get MCS Rate Set -- but only if we are connected at MCS
6012 rates or if we are always reporting max speed or if we have
6013 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006014 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 {
6016 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
6017 rateFlag = 0;
6018 if (rate_flags & eHAL_TX_RATE_HT40)
6019 {
6020 rateFlag |= 1;
6021 }
6022 if (rate_flags & eHAL_TX_RATE_SGI)
6023 {
6024 rateFlag |= 2;
6025 }
6026
6027 for (i = 0; i < MCSLeng; i++)
6028 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006029 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6030 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 {
6032 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6033 {
6034 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6035 break;
6036 }
6037 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006038 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 {
6040 maxRate = currentRate;
6041 maxSpeedMCS = 1;
6042 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6043 }
6044 }
6045 }
6046
6047 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006048 if (((maxRate < myRate) && (0 == rssidx)) ||
6049 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 {
6051 maxRate = myRate;
6052 if (rate_flags & eHAL_TX_RATE_LEGACY)
6053 {
6054 maxSpeedMCS = 0;
6055 }
6056 else
6057 {
6058 maxSpeedMCS = 1;
6059 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6060 }
6061 }
6062
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006063 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 {
6065 sinfo->txrate.legacy = maxRate;
6066#ifdef LINKSPEED_DEBUG_ENABLED
6067 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6068#endif //LINKSPEED_DEBUG_ENABLED
6069 }
6070 else
6071 {
6072 sinfo->txrate.mcs = maxMCSIdx;
6073 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6074 if (rate_flags & eHAL_TX_RATE_SGI)
6075 {
6076 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6077 }
6078 if (rate_flags & eHAL_TX_RATE_HT40)
6079 {
6080 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6081 }
6082#ifdef LINKSPEED_DEBUG_ENABLED
6083 pr_info("Reporting MCS rate %d flags %x\n",
6084 sinfo->txrate.mcs,
6085 sinfo->txrate.flags );
6086#endif //LINKSPEED_DEBUG_ENABLED
6087 }
6088 }
6089 else
6090 {
6091 // report current rate instead of max rate
6092
6093 if (rate_flags & eHAL_TX_RATE_LEGACY)
6094 {
6095 //provide to the UI in units of 100kbps
6096 sinfo->txrate.legacy = myRate;
6097#ifdef LINKSPEED_DEBUG_ENABLED
6098 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6099#endif //LINKSPEED_DEBUG_ENABLED
6100 }
6101 else
6102 {
6103 //must be MCS
6104 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6105 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6106 if (rate_flags & eHAL_TX_RATE_SGI)
6107 {
6108 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6109 }
6110 if (rate_flags & eHAL_TX_RATE_HT40)
6111 {
6112 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6113 }
6114#ifdef LINKSPEED_DEBUG_ENABLED
6115 pr_info("Reporting actual MCS rate %d flags %x\n",
6116 sinfo->txrate.mcs,
6117 sinfo->txrate.flags );
6118#endif //LINKSPEED_DEBUG_ENABLED
6119 }
6120 }
6121 sinfo->filled |= STATION_INFO_TX_BITRATE;
6122
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006123 sinfo->tx_packets =
6124 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6125 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6126 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6127 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6128
6129 sinfo->tx_retries =
6130 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6131 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6132 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6133 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6134
6135 sinfo->tx_failed =
6136 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6137 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6138 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6139 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6140
6141 sinfo->filled |=
6142 STATION_INFO_TX_PACKETS |
6143 STATION_INFO_TX_RETRIES |
6144 STATION_INFO_TX_FAILED;
6145
6146 EXIT();
6147 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006148}
6149
6150static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6151 struct net_device *dev, bool mode, v_SINT_t timeout)
6152{
6153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6154 VOS_STATUS vos_status;
6155
Jeff Johnsone7245742012-09-05 17:12:55 -07006156 ENTER();
6157
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 if (NULL == pAdapter)
6159 {
6160 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6161 return -ENODEV;
6162 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006163 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6164 {
6165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6166 "%s:LOGP in Progress. Ignore!!!", __func__);
6167 return -EAGAIN;
6168 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006169
6170 /**The get power cmd from the supplicant gets updated by the nl only
6171 *on successful execution of the function call
6172 *we are oppositely mapped w.r.t mode in the driver
6173 **/
6174 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6175
Jeff Johnsone7245742012-09-05 17:12:55 -07006176 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 if (VOS_STATUS_E_FAILURE == vos_status)
6178 {
6179 return -EINVAL;
6180 }
6181 return 0;
6182}
6183
6184
6185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6186static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6187 struct net_device *netdev,
6188 u8 key_index)
6189{
Jeff Johnsone7245742012-09-05 17:12:55 -07006190 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006191 return 0;
6192}
6193#endif //LINUX_VERSION_CODE
6194
6195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6196static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6197 struct net_device *dev,
6198 struct ieee80211_txq_params *params)
6199{
Jeff Johnsone7245742012-09-05 17:12:55 -07006200 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 return 0;
6202}
6203#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6204static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6205 struct ieee80211_txq_params *params)
6206{
Jeff Johnsone7245742012-09-05 17:12:55 -07006207 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 return 0;
6209}
6210#endif //LINUX_VERSION_CODE
6211
6212static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6213 struct net_device *dev, u8 *mac)
6214{
6215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudi15407ac2013-01-11 15:30:36 -08006216 VOS_STATUS vos_status;
6217 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006218
Jeff Johnsone7245742012-09-05 17:12:55 -07006219 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6221 {
6222 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6223 return -EINVAL;
6224 }
6225
6226 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6227 {
6228 hddLog( LOGE,
6229 "%s: Wlan Load/Unload is in progress", __func__);
6230 return -EBUSY;
6231 }
6232
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006233 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6234 {
6235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6236 "%s:LOGP in Progress. Ignore!!!", __func__);
6237 return -EAGAIN;
6238 }
6239
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6241#ifdef WLAN_FEATURE_P2P
6242 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6243#endif
6244 )
6245 {
6246 if( NULL == mac )
6247 {
6248 v_U16_t i;
6249 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6250 {
6251 if(pAdapter->aStaInfo[i].isUsed)
6252 {
6253 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6254 hddLog(VOS_TRACE_LEVEL_INFO,
6255 "%s: Delete STA with MAC::"
6256 "%02x:%02x:%02x:%02x:%02x:%02x",
6257 __func__,
6258 macAddr[0], macAddr[1], macAddr[2],
6259 macAddr[3], macAddr[4], macAddr[5]);
6260 hdd_softap_sta_deauth(pAdapter, macAddr);
6261 }
6262 }
6263 }
6264 else
6265 {
Madan Mohan Koyyalamudi15407ac2013-01-11 15:30:36 -08006266
6267 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6268 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6269 {
6270 hddLog(VOS_TRACE_LEVEL_INFO,
6271 "%s: Skip this DEL STA as this is not used::"
6272 "%02x:%02x:%02x:%02x:%02x:%02x",
6273 __func__,
6274 mac[0], mac[1], mac[2],
6275 mac[3], mac[4], mac[5]);
6276 return -ENOENT;
6277 }
6278
6279 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6280 {
6281 hddLog(VOS_TRACE_LEVEL_INFO,
6282 "%s: Skip this DEL STA as deauth is in progress::"
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
6290 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6291
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 hddLog(VOS_TRACE_LEVEL_INFO,
6293 "%s: Delete STA with MAC::"
6294 "%02x:%02x:%02x:%02x:%02x:%02x",
6295 __func__,
6296 mac[0], mac[1], mac[2],
6297 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudi15407ac2013-01-11 15:30:36 -08006298
6299 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6300 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6301 {
6302 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6303 hddLog(VOS_TRACE_LEVEL_INFO,
6304 "%s: STA removal failed for ::"
6305 "%02x:%02x:%02x:%02x:%02x:%02x",
6306 __func__,
6307 mac[0], mac[1], mac[2],
6308 mac[3], mac[4], mac[5]);
6309 return -ENOENT;
6310 }
6311
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 }
6313 }
6314
6315 EXIT();
6316
6317 return 0;
6318}
6319
6320static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6321 struct net_device *dev, u8 *mac, struct station_parameters *params)
6322{
Mohit Khannac0b992f2012-12-04 15:08:18 -08006323#ifdef FEATURE_WLAN_TDLS
6324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6325 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6326 u32 mask, set;
6327 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006328 ENTER();
Mohit Khannac0b992f2012-12-04 15:08:18 -08006329
6330 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6331 {
6332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6333 "Invalid arguments");
6334 return -EINVAL;
6335 }
6336
6337 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6338 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6339 {
6340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6341 "TDLS Disabled in INI OR not enabled in FW.\
6342 Cannot process TDLS commands \n");
6343 return -ENOTSUPP;
6344 }
Lee Hoonkif1431702013-01-24 21:59:00 -08006345 /* first to check if we reached to maximum supported TDLS peer.
6346 TODO: for now, return -EPERM looks working fine,
6347 but need to check if any other errno fit into this category.*/
6348 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6349 {
6350 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6351 "%s: TDLS Max peer already connected. Request declined. \n",
6352 __func__);
6353 return -EPERM;
6354 }
Mohit Khannac0b992f2012-12-04 15:08:18 -08006355
6356 mask = params->sta_flags_mask;
6357
6358 set = params->sta_flags_set;
6359
6360
Lee Hoonkif1431702013-01-24 21:59:00 -08006361 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6362 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khannac0b992f2012-12-04 15:08:18 -08006363
6364 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6365 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6367 "Add TDLS peer");
6368
6369
6370 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6371 pAdapter->sessionId, mac);
6372
6373 if (VOS_STATUS_SUCCESS != status) {
6374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6375 "%s: sme_AddTdlsPeerSta failed!", __func__);
6376 }
6377 }
6378 }
6379#endif
6380
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 return 0;
6382}
6383
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006384
6385#ifdef FEATURE_WLAN_LFR
6386static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006387 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006388{
6389#define MAX_PMKSAIDS_IN_CACHE 8
6390 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006391 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006392 tANI_U32 j=0;
6393 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6394 tHalHandle halHandle;
6395 eHalStatus result;
6396 tANI_U8 BSSIDMatched = 0;
6397
Jeff Johnsone7245742012-09-05 17:12:55 -07006398 ENTER();
6399
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006400 // Validate pAdapter
6401 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6402 {
6403 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6404 return -EINVAL;
6405 }
6406
6407 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6408 {
6409 hddLog( LOGE,
6410 "%s: Wlan Load/Unload is in progress", __func__);
6411 return -EBUSY;
6412 }
6413
6414 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6415 {
6416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6417 "%s:LOGP in Progress. Ignore!!!", __func__);
6418 return -EAGAIN;
6419 }
6420
6421 // Retrieve halHandle
6422 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6423
6424 for (j = 0; j < i; j++)
6425 {
6426 if(vos_mem_compare(PMKIDCache[j].BSSID,
6427 pmksa->bssid, WNI_CFG_BSSID_LEN))
6428 {
6429 /* BSSID matched previous entry. Overwrite it. */
6430 BSSIDMatched = 1;
6431 vos_mem_copy(PMKIDCache[j].BSSID,
6432 pmksa->bssid, WNI_CFG_BSSID_LEN);
6433 vos_mem_copy(PMKIDCache[j].PMKID,
6434 pmksa->pmkid,
6435 CSR_RSN_PMKID_SIZE);
6436 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006437 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006438 dump_bssid(pmksa->bssid);
6439 dump_pmkid(halHandle, pmksa->pmkid);
6440 break;
6441 }
6442 }
6443
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006444 /* Check we compared all entries,if then take the first slot now */
6445 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6446
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006447 if (!BSSIDMatched)
6448 {
6449 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6450 vos_mem_copy(PMKIDCache[i].BSSID,
6451 pmksa->bssid, ETHER_ADDR_LEN);
6452 vos_mem_copy(PMKIDCache[i].PMKID,
6453 pmksa->pmkid,
6454 CSR_RSN_PMKID_SIZE);
6455 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006456 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006457 dump_bssid(pmksa->bssid);
6458 dump_pmkid(halHandle, pmksa->pmkid);
6459 // Increment the HDD Local Cache index
6460 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6461 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6462 }
6463
6464
6465 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6466 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006467 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006468 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006469 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006470 // Finally set the PMKSA ID Cache in CSR
6471 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6472 PMKIDCache,
6473 i );
6474 return 0;
6475}
6476
6477
6478static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006479 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006480{
Jeff Johnsone7245742012-09-05 17:12:55 -07006481 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006482 // TODO: Implement this later.
6483 return 0;
6484}
6485
6486static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6487{
Jeff Johnsone7245742012-09-05 17:12:55 -07006488 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006489 // TODO: Implement this later.
6490 return 0;
6491}
6492#endif
6493
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006494#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6495static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6496 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6497{
6498 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6499 hdd_station_ctx_t *pHddStaCtx;
6500
6501 if (NULL == pAdapter)
6502 {
6503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6504 return -ENODEV;
6505 }
6506
6507 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6508
6509 // Added for debug on reception of Re-assoc Req.
6510 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6511 {
6512 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6513 ftie->ie_len);
6514 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6515 }
6516
6517#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6518 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6519 ftie->ie_len);
6520#endif
6521
6522 // Pass the received FT IEs to SME
6523 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6524 ftie->ie_len);
6525 return 0;
6526}
6527#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006528
Mohit Khannac0b992f2012-12-04 15:08:18 -08006529#ifdef FEATURE_WLAN_TDLS
6530static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6531 u8 *peer, u8 action_code, u8 dialog_token,
6532 u16 status_code, const u8 *buf, size_t len)
6533{
6534
6535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khannac0b992f2012-12-04 15:08:18 -08006537 u8 peerMac[6];
6538 VOS_STATUS status;
Hoonki Leed90d1482013-02-05 22:56:02 -08006539 int responder;
Mohit Khannac0b992f2012-12-04 15:08:18 -08006540
6541 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6542 {
6543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6544 "Invalid arguments");
6545 return -EINVAL;
6546 }
6547
6548 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6549 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6550 {
6551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6552 "TDLS Disabled in INI OR not enabled in FW.\
6553 Cannot process TDLS commands \n");
6554 return -ENOTSUPP;
6555 }
Lee Hoonkif1431702013-01-24 21:59:00 -08006556
6557 if(SIR_MAC_TDLS_SETUP_REQ == action_code ||
6558 SIR_MAC_TDLS_SETUP_RSP == action_code )
6559 {
6560 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6561 {
6562 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6563 we return error code at 'add_station()'. Hence we have this
6564 check again in addtion to add_station().
6565 Anyway, there is no hard to double-check. */
6566 if(SIR_MAC_TDLS_SETUP_REQ == action_code)
6567 {
6568 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6569 "%s: TDLS Max peer already connected. Request declined. \n",
6570 __func__);
6571 return -EPERM;
6572 }
6573 else
6574 {
6575 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6576 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6577 "%s: TDLS Max peer already connected send response status %d \n",
6578 __func__,status_code);
6579 }
6580 }
6581 }
Mohit Khannac0b992f2012-12-04 15:08:18 -08006582 vos_mem_copy( peerMac, peer, 6);
6583
Hoonki Lee068d4142013-01-16 17:40:54 -08006584#ifdef WLAN_FEATURE_TDLS_DEBUG
6585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6586 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6587 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6588 action_code, dialog_token, status_code, len);
6589#endif
Mohit Khannac0b992f2012-12-04 15:08:18 -08006590
Hoonki Leed90d1482013-02-05 22:56:02 -08006591 /*Except teardown responder will not be used so just make 0*/
6592 responder = 0;
6593 if(SIR_MAC_TDLS_TEARDOWN == action_code)
6594 {
6595 responder = wlan_hdd_tdls_get_responder(peerMac);
6596 if(-1 == responder)
6597 {
6598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6599 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6600 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6601 dialog_token, status_code, len);
6602 return -EPERM;
6603 }
Mohit Khannac0b992f2012-12-04 15:08:18 -08006604 }
Mohit Khannac0b992f2012-12-04 15:08:18 -08006605
6606 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leed90d1482013-02-05 22:56:02 -08006607 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khannac0b992f2012-12-04 15:08:18 -08006608
6609 if (VOS_STATUS_SUCCESS != status) {
6610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6611 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6612 }
6613
Hoonki Leed90d1482013-02-05 22:56:02 -08006614 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6615 {
6616 wlan_hdd_tdls_set_responder(peerMac, TRUE);
6617 }
6618 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6619 {
6620 wlan_hdd_tdls_set_responder(peerMac, FALSE);
6621 }
Mohit Khannac0b992f2012-12-04 15:08:18 -08006622
6623 return 0;
6624}
6625
6626static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6627 u8 *peer, enum nl80211_tdls_operation oper)
6628{
6629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6630 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee068d4142013-01-16 17:40:54 -08006631#ifdef WLAN_FEATURE_TDLS_DEBUG
6632 const char *tdls_oper_str[]= {
6633 "NL80211_TDLS_DISCOVERY_REQ",
6634 "NL80211_TDLS_SETUP",
6635 "NL80211_TDLS_TEARDOWN",
6636 "NL80211_TDLS_ENABLE_LINK",
6637 "NL80211_TDLS_DISABLE_LINK",
6638 "NL80211_TDLS_UNKONW_OPER"};
6639#endif
Mohit Khannac0b992f2012-12-04 15:08:18 -08006640
6641 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6642 {
6643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6644 "Invalid arguments");
6645 return -EINVAL;
6646 }
Hoonki Lee068d4142013-01-16 17:40:54 -08006647
6648#ifdef WLAN_FEATURE_TDLS_DEBUG
6649 if((int)oper > 4)
6650 oper = 5;
6651
6652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6653 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6654 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6655 tdls_oper_str[(int)oper]);
6656#endif
Mohit Khannac0b992f2012-12-04 15:08:18 -08006657
6658 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee068d4142013-01-16 17:40:54 -08006659 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khannac0b992f2012-12-04 15:08:18 -08006660 {
Hoonki Lee068d4142013-01-16 17:40:54 -08006661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khannac0b992f2012-12-04 15:08:18 -08006662 "TDLS Disabled in INI OR not enabled in FW.\
6663 Cannot process TDLS commands \n");
6664 return -ENOTSUPP;
6665 }
6666
6667 switch (oper) {
6668 case NL80211_TDLS_ENABLE_LINK:
6669 {
Hoonki Lee068d4142013-01-16 17:40:54 -08006670 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006671 hddTdlsPeer_t *pTdlsPeer;
Mohit Khannac0b992f2012-12-04 15:08:18 -08006672 VOS_STATUS status;
6673
6674 if (peer) {
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006675 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
Mohit Khannac0b992f2012-12-04 15:08:18 -08006676
6677 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006678 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khannac0b992f2012-12-04 15:08:18 -08006679 __func__, peer[0], peer[1],
6680 peer[2], peer[3],
6681 peer[4], peer[5] );
6682
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006683 if ( NULL == pTdlsPeer ) {
6684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6685 __func__, peer[0], peer[1],
6686 peer[2], peer[3],
6687 peer[4], peer[5] );
Hoonki Leebec7bad2013-01-16 19:29:14 -08006688 return -EINVAL;
Mohit Khannac0b992f2012-12-04 15:08:18 -08006689 }
6690
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006691 status = WLANTL_ChangeSTAState( pVosContext, pTdlsPeer->staId,
Mohit Khannac0b992f2012-12-04 15:08:18 -08006692 WLANTL_STA_AUTHENTICATED );
6693
Hoonki Leebec7bad2013-01-16 19:29:14 -08006694 //This can fail only if the staId is not registered yet with TL
6695 //return -EINVAL in such case.
Mohit Khannac0b992f2012-12-04 15:08:18 -08006696 if (0 != status) {
6697 hddLog(VOS_TRACE_LEVEL_ERROR,
6698 "%s: WLANTL_ChangeSTAState failed, returned %d",
6699 __func__, status);
Hoonki Leebec7bad2013-01-16 19:29:14 -08006700 return -EINVAL;
Mohit Khannac0b992f2012-12-04 15:08:18 -08006701 }
Hoonki Leebec7bad2013-01-16 19:29:14 -08006702
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006703 wlan_hdd_tdls_set_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Chilam NGde0b4112013-01-19 12:27:36 +05306704
Mohit Khannac0b992f2012-12-04 15:08:18 -08006705 } else {
6706 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6707 }
6708 }
6709 break;
6710 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkif1431702013-01-24 21:59:00 -08006711 {
Hoonki Lee6ef713f2013-02-05 18:08:43 -08006712 if(NULL != wlan_hdd_tdls_find_peer(peer))
Lee Hoonkif1431702013-01-24 21:59:00 -08006713 {
6714 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6715 pAdapter->sessionId, peer );
6716 }
6717 else
6718 {
6719 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6720 "%s: TDLS Peer Station doesn't exist \n",__func__);
6721 }
6722 return 0;
6723 }
Mohit Khannac0b992f2012-12-04 15:08:18 -08006724 case NL80211_TDLS_TEARDOWN:
6725 case NL80211_TDLS_SETUP:
6726 case NL80211_TDLS_DISCOVERY_REQ:
6727 /* We don't support in-driver setup/teardown/discovery */
6728 return -ENOTSUPP;
6729 default:
6730 return -ENOTSUPP;
6731 }
6732 return 0;
6733}
Chilam NGde0b4112013-01-19 12:27:36 +05306734
6735int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6736 struct net_device *dev, u8 *peer)
6737{
6738 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6739 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6740
6741 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6742 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6743}
Mohit Khannac0b992f2012-12-04 15:08:18 -08006744#endif
6745
Jeff Johnson295189b2012-06-20 16:38:30 -07006746/* cfg80211_ops */
6747static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6748{
6749 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6750 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6751 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6752 .change_station = wlan_hdd_change_station,
6753#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6754 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6755 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6756 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006757#else
6758 .start_ap = wlan_hdd_cfg80211_start_ap,
6759 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6760 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006761#endif
6762 .change_bss = wlan_hdd_cfg80211_change_bss,
6763 .add_key = wlan_hdd_cfg80211_add_key,
6764 .get_key = wlan_hdd_cfg80211_get_key,
6765 .del_key = wlan_hdd_cfg80211_del_key,
6766 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnsoncab8ddc2013-01-18 17:05:29 -08006767#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnsoncab8ddc2013-01-18 17:05:29 -08006769#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 .scan = wlan_hdd_cfg80211_scan,
6771 .connect = wlan_hdd_cfg80211_connect,
6772 .disconnect = wlan_hdd_cfg80211_disconnect,
6773 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6774 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6775 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6776 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6777 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6778#ifdef WLAN_FEATURE_P2P
6779 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6780 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6781 .mgmt_tx = wlan_hdd_action,
6782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6783 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6784 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6785 .set_txq_params = wlan_hdd_set_txq_params,
6786#endif
6787#endif
6788 .get_station = wlan_hdd_cfg80211_get_station,
6789 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6790 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006791 .add_station = wlan_hdd_cfg80211_add_station,
6792#ifdef FEATURE_WLAN_LFR
6793 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6794 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6795 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6796#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006797#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6798 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6799#endif
Mohit Khannac0b992f2012-12-04 15:08:18 -08006800#ifdef FEATURE_WLAN_TDLS
6801 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6802 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6803#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006804};
6805
6806#endif // CONFIG_CFG80211