blob: a7824ab1f5489557757a2939fd6ba241acf0eb42 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**========================================================================
43
44 \file wlan_hdd_cfg80211.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 21/12/09 Ashwani Created module.
69
70 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
71 Ganesh K
72 ==========================================================================*/
73
74#ifdef CONFIG_CFG80211
75
76#include <linux/version.h>
77#include <linux/module.h>
78#include <linux/kernel.h>
79#include <linux/init.h>
80#include <linux/wireless.h>
81#include <wlan_hdd_includes.h>
82#include <net/arp.h>
83#include <net/cfg80211.h>
84#include <linux/wireless.h>
85#include <wlan_hdd_wowl.h>
86#include <aniGlobal.h>
87#include "ccmApi.h"
88#include "sirParams.h"
89#include "dot11f.h"
90#include "wlan_hdd_assoc.h"
91#include "wlan_hdd_wext.h"
92#include "sme_Api.h"
93#include "wlan_hdd_p2p.h"
94#include "wlan_hdd_cfg80211.h"
95#include "wlan_hdd_hostapd.h"
96#include "sapInternal.h"
97#include "wlan_hdd_softap_tx_rx.h"
98#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053099#include "wlan_hdd_assoc.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#ifdef WLAN_BTAMP_FEATURE
101#include "bap_hdd_misc.h"
102#endif
103#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800104#ifdef FEATURE_WLAN_TDLS
105#include "wlan_hdd_tdls.h"
106#endif
Madan Mohan Koyylamudi64267f72013-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 Hoonkic1262f22013-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 Johnson3bbe4bf2013-01-18 17:05:29 -0800358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700359};
360
Sudhir Sattayappa Kohalli278eee52013-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 Ravia72c3992013-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 Kohalli278eee52013-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 Ravia72c3992013-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 Kohalli278eee52013-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 Zmuda77fb5ae2013-01-29 08:00:17 -0800558#ifdef FEATURE_WLAN_LFR
559 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
560#endif
Mohit Khanna698ba2a2012-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 Johnson3bbe4bf2013-01-18 17:05:29 -0800583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700584 | BIT(NL80211_IFTYPE_AP);
585
Sudhir Sattayappa Kohalli278eee52013-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 Koyylamudi64267f72013-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 Koyylamudi64267f72013-02-05 14:07:08 +05301318 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001319 {
Madan Mohan Koyylamudi64267f72013-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 Koyylamudi64267f72013-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 Koyylamudi64267f72013-02-05 14:07:08 +05301336 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 {
Madan Mohan Koyylamudi64267f72013-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 Modi3a32cc52013-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 Koyyalamudi527935a2012-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 Koyyalamudi527935a2012-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 Koyyalamudi527935a2012-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 Koyyalamudi527935a2012-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 Koyyalamudi527935a2012-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 Koyyalamudi527935a2012-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 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001552 else if ( channel == 165 )
1553 {
1554 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1555 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301556 }
1557#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001558 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1559 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301560 {
1561 if ( channel== 40 || channel == 48 || channel == 56 ||
1562 channel == 64 || channel == 104 || channel == 112 ||
1563 channel == 120 || channel == 128 || channel == 136 ||
1564 channel == 144 || channel == 153 || channel == 161 )
1565 {
1566 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1567 }
1568 else if ( channel== 36 || channel == 44 || channel == 52 ||
1569 channel == 60 || channel == 100 || channel == 108 ||
1570 channel == 116 || channel == 124 || channel == 132 ||
1571 channel == 140 || channel == 149 || channel == 157 )
1572 {
1573 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1574 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001575 else if ( channel == 165 )
1576 {
1577 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1578 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301579 }
1580 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1581
1582 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1583 return VOS_STATUS_SUCCESS;
1584}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001585
Jeff Johnson295189b2012-06-20 16:38:30 -07001586#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1587static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1588 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001589#else
1590static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1591 struct cfg80211_beacon_data *params,
1592 const u8 *ssid, size_t ssid_len,
1593 enum nl80211_hidden_ssid hidden_ssid)
1594#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001595{
1596 tsap_Config_t *pConfig;
1597 beacon_data_t *pBeacon = NULL;
1598 struct ieee80211_mgmt *pMgmt_frame;
1599 v_U8_t *pIe=NULL;
1600 v_U16_t capab_info;
1601 eCsrAuthType RSNAuthType;
1602 eCsrEncryptionType RSNEncryptType;
1603 eCsrEncryptionType mcRSNEncryptType;
1604 int status = VOS_STATUS_SUCCESS;
1605 tpWLAN_SAPEventCB pSapEventCallback;
1606 hdd_hostapd_state_t *pHostapdState;
1607 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1608 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301609 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001610 struct qc_mac_acl_entry *acl_entry = NULL;
1611 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001612 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001613
1614 ENTER();
1615
1616 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1617
1618 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1619
1620 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1621
1622 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1623
1624 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1625
1626 //channel is already set in the set_channel Call back
1627 //pConfig->channel = pCommitConfig->channel;
1628
1629 /*Protection parameter to enable or disable*/
1630 pConfig->protEnabled =
1631 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1632
1633 pConfig->dtim_period = pBeacon->dtim_period;
1634
1635 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1636 pConfig->dtim_period);
1637
1638
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001639 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001640 {
1641 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001643 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001645 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001646 pConfig->ieee80211d = 1;
1647 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1648 sme_setRegInfo(hHal, pConfig->countryCode);
1649 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001651 else
1652 {
1653 pConfig->ieee80211d = 0;
1654 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301655 /*
1656 * If auto channel is configured i.e. channel is 0,
1657 * so skip channel validation.
1658 */
1659 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1660 {
1661 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1662 {
1663 hddLog(VOS_TRACE_LEVEL_ERROR,
1664 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1665 return -EINVAL;
1666 }
1667 }
1668 else
1669 {
1670 if(1 != pHddCtx->is_dynamic_channel_range_set)
1671 {
1672 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1673 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1674 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1675 }
1676 pHddCtx->is_dynamic_channel_range_set = 0;
1677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001679 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 {
1681 pConfig->ieee80211d = 0;
1682 }
1683 pConfig->authType = eSAP_AUTO_SWITCH;
1684
1685 capab_info = pMgmt_frame->u.beacon.capab_info;
1686
1687 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1688 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1689
1690 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1691
1692 /*Set wps station to configured*/
1693 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1694
1695 if(pIe)
1696 {
1697 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1698 {
1699 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1700 return -EINVAL;
1701 }
1702 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1703 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001704 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001705 /* Check 15 bit of WPS IE as it contain information for wps state
1706 * WPS state
1707 */
1708 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1709 {
1710 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1711 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1712 {
1713 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1714 }
1715 }
1716 }
1717 else
1718 {
1719 pConfig->wps_state = SAP_WPS_DISABLED;
1720 }
1721 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1722
1723 pConfig->RSNWPAReqIELength = 0;
1724 pConfig->pRSNWPAReqIE = NULL;
1725 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1726 WLAN_EID_RSN);
1727 if(pIe && pIe[1])
1728 {
1729 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1730 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1731 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1732 /* The actual processing may eventually be more extensive than
1733 * this. Right now, just consume any PMKIDs that are sent in
1734 * by the app.
1735 * */
1736 status = hdd_softap_unpackIE(
1737 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1738 &RSNEncryptType,
1739 &mcRSNEncryptType,
1740 &RSNAuthType,
1741 pConfig->pRSNWPAReqIE[1]+2,
1742 pConfig->pRSNWPAReqIE );
1743
1744 if( VOS_STATUS_SUCCESS == status )
1745 {
1746 /* Now copy over all the security attributes you have
1747 * parsed out
1748 * */
1749 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1750 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1751 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1752 = RSNEncryptType;
1753 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1754 "EncryptionType = %d mcEncryptionType = %d\n"),
1755 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1756 }
1757 }
1758
1759 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1760 pBeacon->tail, pBeacon->tail_len);
1761
1762 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1763 {
1764 if (pConfig->pRSNWPAReqIE)
1765 {
1766 /*Mixed mode WPA/WPA2*/
1767 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1768 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1769 }
1770 else
1771 {
1772 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1773 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1774 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1775 status = hdd_softap_unpackIE(
1776 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1777 &RSNEncryptType,
1778 &mcRSNEncryptType,
1779 &RSNAuthType,
1780 pConfig->pRSNWPAReqIE[1]+2,
1781 pConfig->pRSNWPAReqIE );
1782
1783 if( VOS_STATUS_SUCCESS == status )
1784 {
1785 /* Now copy over all the security attributes you have
1786 * parsed out
1787 * */
1788 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1789 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1790 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1791 = RSNEncryptType;
1792 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1793 "EncryptionType = %d mcEncryptionType = %d\n"),
1794 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1795 }
1796 }
1797 }
1798
1799 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1800
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001801#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 if (params->ssid != NULL)
1803 {
1804 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1805 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1806 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1807 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1808 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001809#else
1810 if (ssid != NULL)
1811 {
1812 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1813 pConfig->SSIDinfo.ssid.length = ssid_len;
1814 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1815 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1816 }
1817#endif
1818
Jeff Johnson295189b2012-06-20 16:38:30 -07001819 vos_mem_copy(pConfig->self_macaddr.bytes,
1820 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1821
1822 /* default value */
1823 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1824 pConfig->num_accept_mac = 0;
1825 pConfig->num_deny_mac = 0;
1826
1827 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1828 pBeacon->tail, pBeacon->tail_len);
1829
1830 /* pIe for black list is following form:
1831 type : 1 byte
1832 length : 1 byte
1833 OUI : 4 bytes
1834 acl type : 1 byte
1835 no of mac addr in black list: 1 byte
1836 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1837 */
1838 if ((pIe != NULL) && (pIe[1] != 0))
1839 {
1840 pConfig->SapMacaddr_acl = pIe[6];
1841 pConfig->num_deny_mac = pIe[7];
1842 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1843 pIe[6], pIe[7]);
1844 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1845 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1846 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1847 for (i = 0; i < pConfig->num_deny_mac; i++)
1848 {
1849 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1850 acl_entry++;
1851 }
1852 }
1853 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1854 pBeacon->tail, pBeacon->tail_len);
1855
1856 /* pIe for white list is following form:
1857 type : 1 byte
1858 length : 1 byte
1859 OUI : 4 bytes
1860 acl type : 1 byte
1861 no of mac addr in white list: 1 byte
1862 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1863 */
1864 if ((pIe != NULL) && (pIe[1] != 0))
1865 {
1866 pConfig->SapMacaddr_acl = pIe[6];
1867 pConfig->num_accept_mac = pIe[7];
1868 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1869 pIe[6], pIe[7]);
1870 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1871 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1872 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1873 for (i = 0; i < pConfig->num_accept_mac; i++)
1874 {
1875 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1876 acl_entry++;
1877 }
1878 }
1879 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1880
Jeff Johnsone7245742012-09-05 17:12:55 -07001881#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001882 /* Overwrite the hostapd setting for HW mode only for 11ac.
1883 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1884 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1885 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1886 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1887 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1888 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1889 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001890 {
1891 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1892 }
1893#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301894
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001895 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1896 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 // ht_capab is not what the name conveys,this is used for protection bitmap
1898 pConfig->ht_capab =
1899 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1900
1901 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1902 {
1903 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1904 return -EINVAL;
1905 }
1906
1907 //Uapsd Enabled Bit
1908 pConfig->UapsdEnable =
1909 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1910 //Enable OBSS protection
1911 pConfig->obssProtEnabled =
1912 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1913
1914 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1915 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1916 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1917 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1918 (int)pConfig->channel);
1919 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1920 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1921 pConfig->authType);
1922 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1923 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1924 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1925 pConfig->protEnabled, pConfig->obssProtEnabled);
1926
1927 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1928 {
1929 //Bss already started. just return.
1930 //TODO Probably it should update some beacon params.
1931 hddLog( LOGE, "Bss Already started...Ignore the request");
1932 EXIT();
1933 return 0;
1934 }
1935
1936 pConfig->persona = pHostapdAdapter->device_mode;
1937
1938 pSapEventCallback = hdd_hostapd_SAPEventCB;
1939 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1940 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1941 {
1942 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1943 return -EINVAL;
1944 }
1945
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001946 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1948
1949 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1950
1951 if (!VOS_IS_STATUS_SUCCESS(status))
1952 {
1953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1954 ("ERROR: HDD vos wait for single_event failed!!\n"));
1955 VOS_ASSERT(0);
1956 }
1957
1958 //Succesfully started Bss update the state bit.
1959 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1960
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001961#ifdef WLAN_FEATURE_P2P_DEBUG
1962 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1963 {
1964 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1965 {
1966 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1967 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001968 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001969 }
1970 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1971 {
1972 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1973 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001974 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001975 }
1976 }
1977#endif
1978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 pHostapdState->bCommit = TRUE;
1980 EXIT();
1981
1982 return 0;
1983}
1984
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001986static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1987 struct net_device *dev,
1988 struct beacon_parameters *params)
1989{
1990 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1991 int status=VOS_STATUS_SUCCESS;
1992
1993 ENTER();
1994
1995 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1996
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001997 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1998 {
1999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2000 "%s:LOGP in Progress. Ignore!!!", __func__);
2001 return -EAGAIN;
2002 }
2003
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2005#ifdef WLAN_FEATURE_P2P
2006 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2007#endif
2008 )
2009 {
2010 beacon_data_t *old,*new;
2011
2012 old = pAdapter->sessionCtx.ap.beacon;
2013
2014 if (old)
2015 return -EALREADY;
2016
2017 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2018
2019 if(status != VOS_STATUS_SUCCESS)
2020 {
2021 hddLog(VOS_TRACE_LEVEL_FATAL,
2022 "%s:Error!!! Allocating the new beacon\n",__func__);
2023 return -EINVAL;
2024 }
2025
2026 pAdapter->sessionCtx.ap.beacon = new;
2027
2028 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2029 }
2030
2031 EXIT();
2032 return status;
2033}
2034
2035static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
2036 struct net_device *dev,
2037 struct beacon_parameters *params)
2038{
2039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2040 int status=VOS_STATUS_SUCCESS;
2041
2042 ENTER();
2043
2044 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2045 __func__,pAdapter->device_mode);
2046
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002047 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2048 {
2049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2050 "%s:LOGP in Progress. Ignore!!!", __func__);
2051 return -EAGAIN;
2052 }
2053
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2055#ifdef WLAN_FEATURE_P2P
2056 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2057#endif
2058 )
2059 {
2060 beacon_data_t *old,*new;
2061
2062 old = pAdapter->sessionCtx.ap.beacon;
2063
2064 if (!old)
2065 return -ENOENT;
2066
2067 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2068
2069 if(status != VOS_STATUS_SUCCESS) {
2070 hddLog(VOS_TRACE_LEVEL_FATAL,
2071 "%s: Error!!! Allocating the new beacon\n",__func__);
2072 return -EINVAL;
2073 }
2074
2075 pAdapter->sessionCtx.ap.beacon = new;
2076
2077 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2078 }
2079
2080 EXIT();
2081 return status;
2082}
2083
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002084#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2085
2086#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002087static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2088 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002089#else
2090static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2091 struct net_device *dev)
2092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002093{
2094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002095 hdd_context_t *pHddCtx = NULL;
2096 hdd_scaninfo_t *pScanInfo = NULL;
2097 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 VOS_STATUS status = 0;
2099
2100 ENTER();
2101
2102 if (NULL == pAdapter)
2103 {
2104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002105 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 return -ENODEV;
2107 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002108 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2109 {
2110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2111 "%s:LOGP in Progress. Ignore!!!", __func__);
2112 return -EAGAIN;
2113 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002114
2115 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2116 if (NULL == pHddCtx)
2117 {
2118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002119 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002120 return -ENODEV;
2121 }
2122
2123 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2124 if (NULL == staAdapter)
2125 {
2126 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2127 if (NULL == staAdapter)
2128 {
2129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002130 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002131 return -ENODEV;
2132 }
2133 }
2134
2135 pScanInfo = &pHddCtx->scan_info;
2136
Jeff Johnson295189b2012-06-20 16:38:30 -07002137 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2138 {
2139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2140 return -EAGAIN;
2141 }
2142
2143 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2144
2145 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2146 __func__,pAdapter->device_mode);
2147
Jeff Johnsone7245742012-09-05 17:12:55 -07002148 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2149 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002150 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002151 hdd_abort_mac_scan(staAdapter->pHddCtx);
2152 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002153 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002154 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2155 if (!status)
2156 {
2157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002158 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002159 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002160 VOS_ASSERT(pScanInfo->mScanPending);
2161 return 0;
2162 }
2163 }
2164
Jeff Johnson295189b2012-06-20 16:38:30 -07002165 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2166#ifdef WLAN_FEATURE_P2P
2167 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2168#endif
2169 )
2170 {
2171 beacon_data_t *old;
2172
2173 old = pAdapter->sessionCtx.ap.beacon;
2174
2175 if (!old)
2176 return -ENOENT;
2177
2178#ifdef CONFIG_CFG80211
2179 hdd_cleanup_actionframe(pHddCtx, pAdapter);
2180#endif
2181
2182 mutex_lock(&pHddCtx->sap_lock);
2183 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2184 {
2185 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2186 {
2187 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2188
2189 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2190
2191 if (!VOS_IS_STATUS_SUCCESS(status))
2192 {
2193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2194 ("ERROR: HDD vos wait for single_event failed!!\n"));
2195 VOS_ASSERT(0);
2196 }
2197 }
2198 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2199 }
2200 mutex_unlock(&pHddCtx->sap_lock);
2201
2202 if(status != VOS_STATUS_SUCCESS)
2203 {
2204 hddLog(VOS_TRACE_LEVEL_FATAL,
2205 "%s:Error!!! Stopping the BSS\n",__func__);
2206 return -EINVAL;
2207 }
2208
2209 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2210 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2211 ==eHAL_STATUS_FAILURE)
2212 {
2213 hddLog(LOGE,
2214 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2215 }
2216
2217 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2218 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2219 eANI_BOOLEAN_FALSE) )
2220 {
2221 hddLog(LOGE,
2222 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2223 }
2224
2225 // Reset WNI_CFG_PROBE_RSP Flags
2226 wlan_hdd_reset_prob_rspies(pAdapter);
2227
2228 pAdapter->sessionCtx.ap.beacon = NULL;
2229 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002230#ifdef WLAN_FEATURE_P2P_DEBUG
2231 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2232 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2233 {
2234 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2235 "GO got removed");
2236 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2237 }
2238#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 }
2240 EXIT();
2241 return status;
2242}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002243
2244#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2245
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302246static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2247 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002248 struct cfg80211_ap_settings *params)
2249{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302250 hdd_adapter_t *pAdapter;
2251 hdd_context_t *pHddCtx;
2252 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002253
2254 ENTER();
2255
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302256 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002257 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2259 "%s: Device is Null", __func__);
2260 return -ENODEV;
2261 }
2262
2263 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2264 if (NULL == pAdapter)
2265 {
2266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2267 "%s: HDD adapter is Null", __func__);
2268 return -ENODEV;
2269 }
2270
2271 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2272 {
2273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2274 "%s: HDD adapter magic is invalid", __func__);
2275 return -ENODEV;
2276 }
2277
2278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2279 if (NULL == pHddCtx)
2280 {
2281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2282 "%s: HDD context is Null", __func__);
2283 return -ENODEV;
2284 }
2285
2286 if (pHddCtx->isLogpInProgress)
2287 {
2288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2289 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002290 return -EAGAIN;
2291 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302292
2293 if (pHddCtx->isLoadUnloadInProgress)
2294 {
2295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2296 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2297 return -EAGAIN;
2298 }
2299
2300 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2301 __func__, pAdapter->device_mode);
2302
2303 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002304#ifdef WLAN_FEATURE_P2P
2305 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2306#endif
2307 )
2308 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302309 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002310
2311 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302312
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002313 if (old)
2314 return -EALREADY;
2315
2316 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2317
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302318 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002319 {
2320 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302321 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002322 return -EINVAL;
2323 }
2324 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2326 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2327#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002328 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2329 params->ssid_len, params->hidden_ssid);
2330 }
2331
2332 EXIT();
2333 return status;
2334}
2335
2336
2337static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2338 struct net_device *dev,
2339 struct cfg80211_beacon_data *params)
2340{
2341 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2342 int status=VOS_STATUS_SUCCESS;
2343
2344 ENTER();
2345
2346 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2347 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002348 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2349 {
2350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2351 return -EAGAIN;
2352 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002353
2354 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2355#ifdef WLAN_FEATURE_P2P
2356 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2357#endif
2358 )
2359 {
2360 beacon_data_t *old,*new;
2361
2362 old = pAdapter->sessionCtx.ap.beacon;
2363
2364 if (!old)
2365 return -ENOENT;
2366
2367 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2368
2369 if(status != VOS_STATUS_SUCCESS) {
2370 hddLog(VOS_TRACE_LEVEL_FATAL,
2371 "%s: Error!!! Allocating the new beacon\n",__func__);
2372 return -EINVAL;
2373 }
2374
2375 pAdapter->sessionCtx.ap.beacon = new;
2376
2377 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2378 }
2379
2380 EXIT();
2381 return status;
2382}
2383
2384#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2385
Jeff Johnson295189b2012-06-20 16:38:30 -07002386
2387static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2388 struct net_device *dev,
2389 struct bss_parameters *params)
2390{
2391 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2392
2393 ENTER();
2394
2395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2396 __func__,pAdapter->device_mode);
2397
2398 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2399#ifdef WLAN_FEATURE_P2P
2400 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2401#endif
2402 )
2403 {
2404 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2405 * want to update this parameter */
2406 if (-1 != params->ap_isolate)
2407 {
2408 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2409 }
2410 }
2411
2412 EXIT();
2413 return 0;
2414}
2415
2416/*
2417 * FUNCTION: wlan_hdd_cfg80211_change_iface
2418 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2419 */
2420int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2421 struct net_device *ndev,
2422 enum nl80211_iftype type,
2423 u32 *flags,
2424 struct vif_params *params
2425 )
2426{
2427 struct wireless_dev *wdev;
2428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2429 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002430 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002431 tCsrRoamProfile *pRoamProfile = NULL;
2432 eCsrRoamBssType LastBSSType;
2433 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2434 eMib_dot11DesiredBssType connectedBssType;
2435 VOS_STATUS status;
2436
2437 ENTER();
2438
2439 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2440 {
2441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2442 return -EAGAIN;
2443 }
2444
2445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2446 __func__, pAdapter->device_mode);
2447
2448 wdev = ndev->ieee80211_ptr;
2449
2450#ifdef WLAN_BTAMP_FEATURE
2451 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2452 (NL80211_IFTYPE_ADHOC == type)||
2453 (NL80211_IFTYPE_AP == type)||
2454 (NL80211_IFTYPE_P2P_GO == type))
2455 {
2456 pHddCtx->isAmpAllowed = VOS_FALSE;
2457 // stop AMP traffic
2458 status = WLANBAP_StopAmp();
2459 if(VOS_STATUS_SUCCESS != status )
2460 {
2461 pHddCtx->isAmpAllowed = VOS_TRUE;
2462 hddLog(VOS_TRACE_LEVEL_FATAL,
2463 "%s: Failed to stop AMP", __func__);
2464 return -EINVAL;
2465 }
2466 }
2467#endif //WLAN_BTAMP_FEATURE
2468 /* Reset the current device mode bit mask*/
2469 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2470
2471 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2472#ifdef WLAN_FEATURE_P2P
2473 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002474 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002475#endif
2476 )
2477 {
2478 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2479 pRoamProfile = &pWextState->roamProfile;
2480 LastBSSType = pRoamProfile->BSSType;
2481
2482 switch (type)
2483 {
2484 case NL80211_IFTYPE_STATION:
2485#ifdef WLAN_FEATURE_P2P
2486 case NL80211_IFTYPE_P2P_CLIENT:
2487#endif
2488 hddLog(VOS_TRACE_LEVEL_INFO,
2489 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2490 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002491#ifdef WLAN_FEATURE_11AC
2492 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2493 {
2494 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2495 }
2496#endif
2497 pRoamProfile->phyMode =
2498 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002499 wdev->iftype = type;
2500#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002501 //Check for sub-string p2p to confirm its a p2p interface
2502 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002503 {
2504 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2505 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2506 }
2507 else
2508 {
2509 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002510 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002511 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002512#endif
2513 break;
2514 case NL80211_IFTYPE_ADHOC:
2515 hddLog(VOS_TRACE_LEVEL_INFO,
2516 "%s: setting interface Type to ADHOC", __func__);
2517 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2518 pRoamProfile->phyMode =
2519 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2520 wdev->iftype = type;
2521 break;
2522
2523 case NL80211_IFTYPE_AP:
2524#ifdef WLAN_FEATURE_P2P
2525 case NL80211_IFTYPE_P2P_GO:
2526#endif
2527 {
2528 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2529 "%s: setting interface Type to %s", __func__,
2530 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2531
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002532 //Cancel any remain on channel for GO mode
2533 if (NL80211_IFTYPE_P2P_GO == type)
2534 {
2535 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2536 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002537 if (NL80211_IFTYPE_AP == type)
2538 {
2539 /* As Loading WLAN Driver one interface being created for p2p device
2540 * address. This will take one HW STA and the max number of clients
2541 * that can connect to softAP will be reduced by one. so while changing
2542 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2543 * interface as it is not required in SoftAP mode.
2544 */
2545
2546 // Get P2P Adapter
2547 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2548
2549 if (pP2pAdapter)
2550 {
2551 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2552 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2553 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2554 }
2555 }
2556
Jeff Johnson295189b2012-06-20 16:38:30 -07002557 //De-init the adapter.
2558 hdd_stop_adapter( pHddCtx, pAdapter );
2559 hdd_deinit_adapter( pHddCtx, pAdapter );
2560 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2561#ifdef WLAN_SOFTAP_FEATURE
2562#ifdef WLAN_FEATURE_P2P
2563 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2564 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2565#else
2566 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2567#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002568
2569 //Disable BMPS and IMPS if enabled
2570 //before starting Go
2571 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2572 {
2573 if(VOS_STATUS_E_FAILURE ==
2574 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2575 {
2576 //Fail to Exit BMPS
2577 VOS_ASSERT(0);
2578 }
2579 }
2580
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002581 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2582 (pConfig->apRandomBssidEnabled))
2583 {
2584 /* To meet Android requirements create a randomized
2585 MAC address of the form 02:1A:11:Fx:xx:xx */
2586 get_random_bytes(&ndev->dev_addr[3], 3);
2587 ndev->dev_addr[0] = 0x02;
2588 ndev->dev_addr[1] = 0x1A;
2589 ndev->dev_addr[2] = 0x11;
2590 ndev->dev_addr[3] |= 0xF0;
2591 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2592 VOS_MAC_ADDR_SIZE);
2593 pr_info("wlan: Generated HotSpot BSSID "
2594 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2595 ndev->dev_addr[0],
2596 ndev->dev_addr[1],
2597 ndev->dev_addr[2],
2598 ndev->dev_addr[3],
2599 ndev->dev_addr[4],
2600 ndev->dev_addr[5]);
2601 }
2602
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 hdd_set_ap_ops( pAdapter->dev );
2604
2605 status = hdd_init_ap_mode(pAdapter);
2606 if(status != VOS_STATUS_SUCCESS)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_FATAL,
2609 "%s: Error initializing the ap mode", __func__);
2610 return -EINVAL;
2611 }
2612 hdd_set_conparam(1);
2613
2614#endif
2615 /*interface type changed update in wiphy structure*/
2616 if(wdev)
2617 {
2618 wdev->iftype = type;
2619 pHddCtx->change_iface = type;
2620 }
2621 else
2622 {
2623 hddLog(VOS_TRACE_LEVEL_ERROR,
2624 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2625 return -EINVAL;
2626 }
2627 goto done;
2628 }
2629
2630 default:
2631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2632 __func__);
2633 return -EOPNOTSUPP;
2634 }
2635 }
2636 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2637#ifdef WLAN_FEATURE_P2P
2638 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2639#endif
2640 )
2641 {
2642 switch(type)
2643 {
2644 case NL80211_IFTYPE_STATION:
2645#ifdef WLAN_FEATURE_P2P
2646 case NL80211_IFTYPE_P2P_CLIENT:
2647#endif
2648 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002649 hdd_stop_adapter( pHddCtx, pAdapter );
2650 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002651 wdev->iftype = type;
2652#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002653 //Check for sub-string p2p to confirm its a p2p interface
2654 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002655 {
2656 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2657 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2658 }
2659 else
2660 {
2661 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002662 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002663 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002664#endif
2665 hdd_set_conparam(0);
2666 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002667 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2668 hdd_set_station_ops( pAdapter->dev );
2669 status = hdd_init_station_mode( pAdapter );
2670 if( VOS_STATUS_SUCCESS != status )
2671 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002672 /* In case of JB, for P2P-GO, only change interface will be called,
2673 * This is the right place to enable back bmps_imps()
2674 */
2675 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002676 goto done;
2677 case NL80211_IFTYPE_AP:
2678#ifdef WLAN_FEATURE_P2P
2679 case NL80211_IFTYPE_P2P_GO:
2680#endif
2681 wdev->iftype = type;
2682#ifdef WLAN_FEATURE_P2P
2683 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2684 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2685#endif
2686 goto done;
2687 default:
2688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2689 __func__);
2690 return -EOPNOTSUPP;
2691
2692 }
2693
2694 }
2695 else
2696 {
2697 return -EOPNOTSUPP;
2698 }
2699
2700
2701 if(pRoamProfile)
2702 {
2703 if ( LastBSSType != pRoamProfile->BSSType )
2704 {
2705 /*interface type changed update in wiphy structure*/
2706 wdev->iftype = type;
2707
2708 /*the BSS mode changed, We need to issue disconnect
2709 if connected or in IBSS disconnect state*/
2710 if ( hdd_connGetConnectedBssType(
2711 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2712 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2713 {
2714 /*need to issue a disconnect to CSR.*/
2715 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2716 if( eHAL_STATUS_SUCCESS ==
2717 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2718 pAdapter->sessionId,
2719 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2720 {
2721 wait_for_completion_interruptible_timeout(
2722 &pAdapter->disconnect_comp_var,
2723 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2724 }
2725 }
2726 }
2727 }
2728
2729done:
2730 /*set bitmask based on updated value*/
2731 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2732#ifdef WLAN_BTAMP_FEATURE
2733 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2734 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2735 {
2736 //we are ok to do AMP
2737 pHddCtx->isAmpAllowed = VOS_TRUE;
2738 }
2739#endif //WLAN_BTAMP_FEATURE
2740 EXIT();
2741 return 0;
2742}
2743
2744static int wlan_hdd_change_station(struct wiphy *wiphy,
2745 struct net_device *dev,
2746 u8 *mac,
2747 struct station_parameters *params)
2748{
2749 VOS_STATUS status = VOS_STATUS_SUCCESS;
2750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2751 v_MACADDR_t STAMacAddress;
2752
Jeff Johnsone7245742012-09-05 17:12:55 -07002753 ENTER();
2754
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002755 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2756 {
2757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2758 "%s:LOGP in Progress. Ignore!!!", __func__);
2759 return -EAGAIN;
2760 }
2761
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2763
2764 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2765#ifdef WLAN_FEATURE_P2P
2766 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2767#endif
2768 )
2769 {
2770 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2771 {
2772 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2773 WLANTL_STA_AUTHENTICATED);
2774
2775 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002776 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002777 return -EINVAL;
2778 }
2779 }
2780
Jeff Johnsone7245742012-09-05 17:12:55 -07002781 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002782 return status;
2783}
2784
2785/*
2786 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2787 * This function is used to get peer station index in IBSS mode
2788 */
2789static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2790{
2791 u8 idx = 0;
2792 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2793 ENTER();
2794 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2795 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2796 {
2797 if ( (0 !=
2798 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2799 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2800 temp, VOS_MAC_ADDR_SIZE)
2801 )
2802 {
2803 return idx;
2804 }
2805 }
2806 return idx;
2807}
2808
2809
2810/*
2811 * FUNCTION: wlan_hdd_cfg80211_add_key
2812 * This function is used to initialize the key information
2813 */
2814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2815static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2816 struct net_device *ndev,
2817 u8 key_index, bool pairwise,
2818 const u8 *mac_addr,
2819 struct key_params *params
2820 )
2821#else
2822static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2823 struct net_device *ndev,
2824 u8 key_index, const u8 *mac_addr,
2825 struct key_params *params
2826 )
2827#endif
2828{
2829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2830 tCsrRoamSetKey setKey;
2831 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2832 int status = 0;
2833 v_U32_t roamId= 0xFF;
2834 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2835 hdd_hostapd_state_t *pHostapdState;
2836 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002837 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002838
2839 ENTER();
2840
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002841 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2842 {
2843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2844 "%s:LOGP in Progress. Ignore!!!", __func__);
2845 return -EAGAIN;
2846 }
2847
Jeff Johnson295189b2012-06-20 16:38:30 -07002848 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2849 __func__,pAdapter->device_mode);
2850
2851 if (CSR_MAX_NUM_KEY <= key_index)
2852 {
2853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2854 key_index);
2855
2856 return -EINVAL;
2857 }
2858
2859 hddLog(VOS_TRACE_LEVEL_INFO,
2860 "%s: called with key index = %d & key length %d",
2861 __func__, key_index, params->key_len);
2862
2863 /*extract key idx, key len and key*/
2864 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2865 setKey.keyId = key_index;
2866 setKey.keyLength = params->key_len;
2867 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2868
2869 switch (params->cipher)
2870 {
2871 case WLAN_CIPHER_SUITE_WEP40:
2872 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2873 break;
2874
2875 case WLAN_CIPHER_SUITE_WEP104:
2876 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2877 break;
2878
2879 case WLAN_CIPHER_SUITE_TKIP:
2880 {
2881 u8 *pKey = &setKey.Key[0];
2882 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2883
2884 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2885
2886 /*Supplicant sends the 32bytes key in this order
2887
2888 |--------------|----------|----------|
2889 | Tk1 |TX-MIC | RX Mic |
2890 |--------------|----------|----------|
2891 <---16bytes---><--8bytes--><--8bytes-->
2892
2893 */
2894 /*Sme expects the 32 bytes key to be in the below order
2895
2896 |--------------|----------|----------|
2897 | Tk1 |RX-MIC | TX Mic |
2898 |--------------|----------|----------|
2899 <---16bytes---><--8bytes--><--8bytes-->
2900 */
2901 /* Copy the Temporal Key 1 (TK1) */
2902 vos_mem_copy(pKey, params->key,16);
2903
2904 /*Copy the rx mic first*/
2905 vos_mem_copy(&pKey[16],&params->key[24],8);
2906
2907 /*Copy the tx mic */
2908 vos_mem_copy(&pKey[24],&params->key[16],8);
2909
2910
2911 break;
2912 }
2913
2914 case WLAN_CIPHER_SUITE_CCMP:
2915 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2916 break;
2917
2918#ifdef FEATURE_WLAN_WAPI
2919 case WLAN_CIPHER_SUITE_SMS4:
2920 {
2921 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2922 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2923 params->key, params->key_len);
2924 return 0;
2925 }
2926#endif
2927#ifdef FEATURE_WLAN_CCX
2928 case WLAN_CIPHER_SUITE_KRK:
2929 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2930 break;
2931#endif
2932 default:
2933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2934 __func__, params->cipher);
2935 return -EOPNOTSUPP;
2936 }
2937
2938 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2939 __func__, setKey.encType);
2940
2941
2942
2943 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2944#ifdef WLAN_FEATURE_P2P
2945 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2946#endif
2947 )
2948 {
2949
2950
2951 if (
2952#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2953 (!pairwise)
2954#else
2955 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2956#endif
2957 )
2958 {
2959 /* set group key*/
2960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08002961 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002962 __func__, __LINE__);
2963 setKey.keyDirection = eSIR_RX_ONLY;
2964 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2965 }
2966 else
2967 {
2968 /* set pairwise key*/
2969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2970 "%s- %d: setting pairwise key",
2971 __func__, __LINE__);
2972 setKey.keyDirection = eSIR_TX_RX;
2973 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2974 }
2975
2976 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2977 if( pHostapdState->bssState == BSS_START )
2978 {
2979 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2980
2981 if ( status != eHAL_STATUS_SUCCESS )
2982 {
2983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2984 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2985 __LINE__, status );
2986 }
2987 }
2988
2989 /* Saving WEP keys */
2990 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2991 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2992 {
2993 //Save the wep key in ap context. Issue setkey after the BSS is started.
2994 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2995 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2996 }
2997 else
2998 {
2999 //Save the key in ap context. Issue setkey after the BSS is started.
3000 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3001 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3002 }
3003 }
3004 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3005#ifdef WLAN_FEATURE_P2P
3006 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3007#endif
3008 )
3009 {
3010 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3011 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3012
3013 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3014
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003015 pWextState->roamProfile.Keys.defaultIndex = key_index;
3016
3017
Jeff Johnson295189b2012-06-20 16:38:30 -07003018 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3019 params->key, params->key_len);
3020
3021 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3022
3023 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3024 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3025 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3026 )
3027 &&
3028 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3029 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3030 )
3031 )
3032 {
3033 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3034 * interface, copy bssid for pairwise key and group macaddr for
3035 * group key initialization*/
3036
3037 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3038
3039 pWextState->roamProfile.negotiatedUCEncryptionType =
3040 pHddStaCtx->conn_info.ucEncryptionType =
3041 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3042 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3043 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3044
3045
3046 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3047 "%s: Negotiated encryption type %d", __func__,
3048 pWextState->roamProfile.negotiatedUCEncryptionType);
3049
3050 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3051 &pWextState->roamProfile, true);
3052 setKey.keyLength = 0;
3053 setKey.keyDirection = eSIR_TX_RX;
3054
3055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3056 if (pairwise)
3057 {
3058#endif
3059 if (mac_addr)
3060 {
3061 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3062 }
3063 else
3064 {
3065 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3066 * and peerMacAddress in case of IBSS*/
3067 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3068 {
3069 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3070 if (HDD_MAX_NUM_IBSS_STA != staidx)
3071 {
3072 vos_mem_copy(setKey.peerMac,
3073 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3074 WNI_CFG_BSSID_LEN);
3075
3076 }
3077 else
3078 {
3079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3080 __func__);
3081 return -EOPNOTSUPP;
3082 }
3083 }
3084 else
3085 {
3086 vos_mem_copy(setKey.peerMac,
3087 &pHddStaCtx->conn_info.bssId[0],
3088 WNI_CFG_BSSID_LEN);
3089 }
3090 }
3091#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3092 }
3093 else
3094 {
3095 /* set group key*/
3096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3097 "%s- %d: setting Group key",
3098 __func__, __LINE__);
3099 setKey.keyDirection = eSIR_RX_ONLY;
3100 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3101 }
3102#endif
3103 }
3104 else if (
3105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3106 (!pairwise)
3107#else
3108 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3109#endif
3110 )
3111 {
3112 /* set group key*/
3113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3114 "%s- %d: setting Group key",
3115 __func__, __LINE__);
3116 setKey.keyDirection = eSIR_RX_ONLY;
3117 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3118 }
3119 else
3120 {
3121 /* set pairwise key*/
3122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3123 "%s- %d: setting pairwise key",
3124 __func__, __LINE__);
3125 setKey.keyDirection = eSIR_TX_RX;
3126 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3127 }
3128
3129 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3130 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3131 __func__, setKey.peerMac[0], setKey.peerMac[1],
3132 setKey.peerMac[2], setKey.peerMac[3],
3133 setKey.peerMac[4], setKey.peerMac[5],
3134 setKey.keyDirection);
3135
3136 vos_status = wlan_hdd_check_ula_done(pAdapter);
3137
3138 if ( vos_status != VOS_STATUS_SUCCESS )
3139 {
3140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3141 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3142 __LINE__, vos_status );
3143
3144 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3145
3146 return -EINVAL;
3147
3148 }
3149
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003150#ifdef WLAN_FEATURE_VOWIFI_11R
3151 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3152 Save the key in the UMAC and include it in the ADD BSS request */
3153 /*TODO 11r - is this used?? */
3154 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
3155 if( halStatus == eHAL_STATUS_SUCCESS )
3156 {
3157 return halStatus;
3158 }
3159#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003160
3161 /* issue set key request to SME*/
3162 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3163 pAdapter->sessionId, &setKey, &roamId );
3164
3165 if ( 0 != status )
3166 {
3167 hddLog(VOS_TRACE_LEVEL_ERROR,
3168 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3169 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3170 return -EINVAL;
3171 }
3172
3173
3174 /* in case of IBSS as there was no information available about WEP keys during
3175 * IBSS join, group key intialized with NULL key, so re-initialize group key
3176 * with correct value*/
3177 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3178 !( ( IW_AUTH_KEY_MGMT_802_1X
3179 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3180 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3181 )
3182 &&
3183 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3184 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3185 )
3186 )
3187 {
3188 setKey.keyDirection = eSIR_RX_ONLY;
3189 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3190
3191 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3192 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3193 __func__, setKey.peerMac[0], setKey.peerMac[1],
3194 setKey.peerMac[2], setKey.peerMac[3],
3195 setKey.peerMac[4], setKey.peerMac[5],
3196 setKey.keyDirection);
3197
3198 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3199 pAdapter->sessionId, &setKey, &roamId );
3200
3201 if ( 0 != status )
3202 {
3203 hddLog(VOS_TRACE_LEVEL_ERROR,
3204 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3205 __func__, status);
3206 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3207 return -EINVAL;
3208 }
3209 }
3210 }
3211
3212 return 0;
3213}
3214
3215/*
3216 * FUNCTION: wlan_hdd_cfg80211_get_key
3217 * This function is used to get the key information
3218 */
3219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3220static int wlan_hdd_cfg80211_get_key(
3221 struct wiphy *wiphy,
3222 struct net_device *ndev,
3223 u8 key_index, bool pairwise,
3224 const u8 *mac_addr, void *cookie,
3225 void (*callback)(void *cookie, struct key_params*)
3226 )
3227#else
3228static int wlan_hdd_cfg80211_get_key(
3229 struct wiphy *wiphy,
3230 struct net_device *ndev,
3231 u8 key_index, const u8 *mac_addr, void *cookie,
3232 void (*callback)(void *cookie, struct key_params*)
3233 )
3234#endif
3235{
3236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3237 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3238 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3239 struct key_params params;
3240
3241 ENTER();
3242
3243 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3244 __func__,pAdapter->device_mode);
3245
3246 memset(&params, 0, sizeof(params));
3247
3248 if (CSR_MAX_NUM_KEY <= key_index)
3249 {
3250 return -EINVAL;
3251 }
3252
3253 switch(pRoamProfile->EncryptionType.encryptionType[0])
3254 {
3255 case eCSR_ENCRYPT_TYPE_NONE:
3256 params.cipher = IW_AUTH_CIPHER_NONE;
3257 break;
3258
3259 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3260 case eCSR_ENCRYPT_TYPE_WEP40:
3261 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3262 break;
3263
3264 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3265 case eCSR_ENCRYPT_TYPE_WEP104:
3266 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3267 break;
3268
3269 case eCSR_ENCRYPT_TYPE_TKIP:
3270 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3271 break;
3272
3273 case eCSR_ENCRYPT_TYPE_AES:
3274 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3275 break;
3276
3277 default:
3278 params.cipher = IW_AUTH_CIPHER_NONE;
3279 break;
3280 }
3281
3282 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3283 params.seq_len = 0;
3284 params.seq = NULL;
3285 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3286 callback(cookie, &params);
3287 return 0;
3288}
3289
3290/*
3291 * FUNCTION: wlan_hdd_cfg80211_del_key
3292 * This function is used to delete the key information
3293 */
3294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3295static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3296 struct net_device *ndev,
3297 u8 key_index,
3298 bool pairwise,
3299 const u8 *mac_addr
3300 )
3301#else
3302static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3303 struct net_device *ndev,
3304 u8 key_index,
3305 const u8 *mac_addr
3306 )
3307#endif
3308{
3309 int status = 0;
3310
3311 //This code needs to be revisited. There is sme_removeKey API, we should
3312 //plan to use that. After the change to use correct index in setkey,
3313 //it is observed that this is invalidating peer
3314 //key index whenever re-key is done. This is affecting data link.
3315 //It should be ok to ignore del_key.
3316#if 0
3317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3318 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3319 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3320 tCsrRoamSetKey setKey;
3321 v_U32_t roamId= 0xFF;
3322
3323 ENTER();
3324
3325 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3326 __func__,pAdapter->device_mode);
3327
3328 if (CSR_MAX_NUM_KEY <= key_index)
3329 {
3330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3331 key_index);
3332
3333 return -EINVAL;
3334 }
3335
3336 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3337 setKey.keyId = key_index;
3338
3339 if (mac_addr)
3340 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3341 else
3342 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3343
3344 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3345
3346 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3347#ifdef WLAN_FEATURE_P2P
3348 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3349#endif
3350 )
3351 {
3352
3353 hdd_hostapd_state_t *pHostapdState =
3354 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3355 if( pHostapdState->bssState == BSS_START)
3356 {
3357 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3358
3359 if ( status != eHAL_STATUS_SUCCESS )
3360 {
3361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3362 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3363 __LINE__, status );
3364 }
3365 }
3366 }
3367 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3368#ifdef WLAN_FEATURE_P2P
3369 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3370#endif
3371 )
3372 {
3373 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3374
3375 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3376
3377 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3378 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3379 __func__, setKey.peerMac[0], setKey.peerMac[1],
3380 setKey.peerMac[2], setKey.peerMac[3],
3381 setKey.peerMac[4], setKey.peerMac[5]);
3382 if(pAdapter->sessionCtx.station.conn_info.connState ==
3383 eConnectionState_Associated)
3384 {
3385 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3386 pAdapter->sessionId, &setKey, &roamId );
3387
3388 if ( 0 != status )
3389 {
3390 hddLog(VOS_TRACE_LEVEL_ERROR,
3391 "%s: sme_RoamSetKey failure, returned %d",
3392 __func__, status);
3393 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3394 return -EINVAL;
3395 }
3396 }
3397 }
3398#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003399 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003400 return status;
3401}
3402
3403/*
3404 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3405 * This function is used to set the default tx key index
3406 */
3407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3408static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3409 struct net_device *ndev,
3410 u8 key_index,
3411 bool unicast, bool multicast)
3412#else
3413static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3414 struct net_device *ndev,
3415 u8 key_index)
3416#endif
3417{
3418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3419 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3420 int status = 0;
3421 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3422
3423 ENTER();
3424
3425 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3426 __func__,pAdapter->device_mode, key_index);
3427
3428 if (CSR_MAX_NUM_KEY <= key_index)
3429 {
3430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3431 key_index);
3432
3433 return -EINVAL;
3434 }
3435
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003436 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3437 {
3438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3439 "%s:LOGP in Progress. Ignore!!!", __func__);
3440 return -EAGAIN;
3441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003442
3443 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3444#ifdef WLAN_FEATURE_P2P
3445 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3446#endif
3447 )
3448 {
3449 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3450 (eCSR_ENCRYPT_TYPE_TKIP !=
3451 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3452 (eCSR_ENCRYPT_TYPE_AES !=
3453 pWextState->roamProfile.EncryptionType.encryptionType[0])
3454 )
3455 {
3456 /* if default key index is not same as previous one,
3457 * then update the default key index */
3458
3459 tCsrRoamSetKey setKey;
3460 v_U32_t roamId= 0xFF;
3461 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3462
3463 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3464 __func__, key_index);
3465
3466 Keys->defaultIndex = (u8)key_index;
3467 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3468 setKey.keyId = key_index;
3469 setKey.keyLength = Keys->KeyLength[key_index];
3470
3471 vos_mem_copy(&setKey.Key[0],
3472 &Keys->KeyMaterial[key_index][0],
3473 Keys->KeyLength[key_index]);
3474
3475 setKey.keyDirection = eSIR_TX_ONLY;
3476
3477 vos_mem_copy(setKey.peerMac,
3478 &pHddStaCtx->conn_info.bssId[0],
3479 WNI_CFG_BSSID_LEN);
3480
3481 setKey.encType =
3482 pWextState->roamProfile.EncryptionType.encryptionType[0];
3483
3484 /* issue set key request */
3485 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3486 pAdapter->sessionId, &setKey, &roamId );
3487
3488 if ( 0 != status )
3489 {
3490 hddLog(VOS_TRACE_LEVEL_ERROR,
3491 "%s: sme_RoamSetKey failed, returned %d", __func__,
3492 status);
3493 return -EINVAL;
3494 }
3495 }
3496 }
3497
3498 /* In SoftAp mode setting key direction for default mode */
3499 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3500 {
3501 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3502 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3503 (eCSR_ENCRYPT_TYPE_AES !=
3504 pWextState->roamProfile.EncryptionType.encryptionType[0])
3505 )
3506 {
3507 /* Saving key direction for default key index to TX default */
3508 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3509 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3510 }
3511 }
3512
3513 return status;
3514}
3515
Jeff Johnson295189b2012-06-20 16:38:30 -07003516/*
3517 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3518 * This function is used to inform the BSS details to nl80211 interface.
3519 */
3520static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3521 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3522{
3523 struct net_device *dev = pAdapter->dev;
3524 struct wireless_dev *wdev = dev->ieee80211_ptr;
3525 struct wiphy *wiphy = wdev->wiphy;
3526 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3527 int chan_no;
3528 int ie_length;
3529 const char *ie;
3530 unsigned int freq;
3531 struct ieee80211_channel *chan;
3532 int rssi = 0;
3533 struct cfg80211_bss *bss = NULL;
3534
3535 ENTER();
3536
3537 if( NULL == pBssDesc )
3538 {
3539 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3540 return bss;
3541 }
3542
3543 chan_no = pBssDesc->channelId;
3544 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3545 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3546
3547 if( NULL == ie )
3548 {
3549 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3550 return bss;
3551 }
3552
3553#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3554 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3555 {
3556 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3557 }
3558 else
3559 {
3560 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3561 }
3562#else
3563 freq = ieee80211_channel_to_frequency(chan_no);
3564#endif
3565
3566 chan = __ieee80211_get_channel(wiphy, freq);
3567
3568 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3569 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3570 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3571 if (bss == NULL)
3572 {
3573 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3574
3575 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3576 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3577 pBssDesc->capabilityInfo,
3578 pBssDesc->beaconInterval, ie, ie_length,
3579 rssi, GFP_KERNEL ));
3580}
3581 else
3582 {
3583 return bss;
3584 }
3585}
3586
3587
3588
3589/*
3590 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3591 * This function is used to inform the BSS details to nl80211 interface.
3592 */
3593struct cfg80211_bss*
3594wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3595 tSirBssDescription *bss_desc
3596 )
3597{
3598 /*
3599 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3600 already exists in bss data base of cfg80211 for that particular BSS ID.
3601 Using cfg80211_inform_bss_frame to update the bss entry instead of
3602 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3603 now there is no possibility to get the mgmt(probe response) frame from PE,
3604 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3605 cfg80211_inform_bss_frame.
3606 */
3607 struct net_device *dev = pAdapter->dev;
3608 struct wireless_dev *wdev = dev->ieee80211_ptr;
3609 struct wiphy *wiphy = wdev->wiphy;
3610 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003611#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3612 qcom_ie_age *qie_age = NULL;
3613 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3614#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003615 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003617 const char *ie =
3618 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3619 unsigned int freq;
3620 struct ieee80211_channel *chan;
3621 struct ieee80211_mgmt *mgmt =
3622 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3623 struct cfg80211_bss *bss_status = NULL;
3624 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3625 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003626#ifdef WLAN_OPEN_SOURCE
3627 struct timespec ts;
3628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003629
3630 ENTER();
3631
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003632 if (!mgmt)
3633 return NULL;
3634
Jeff Johnson295189b2012-06-20 16:38:30 -07003635 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003636
3637#ifdef WLAN_OPEN_SOURCE
3638 /* Android does not want the timestamp from the frame.
3639 Instead it wants a monotonic increasing value */
3640 get_monotonic_boottime(&ts);
3641 mgmt->u.probe_resp.timestamp =
3642 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3643#else
3644 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003645 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3646 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003647
3648#endif
3649
Jeff Johnson295189b2012-06-20 16:38:30 -07003650 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3651 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003652
3653#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3654 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3655 /* Assuming this is the last IE, copy at the end */
3656 ie_length -=sizeof(qcom_ie_age);
3657 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3658 qie_age->element_id = QCOM_VENDOR_IE_ID;
3659 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3660 qie_age->oui_1 = QCOM_OUI1;
3661 qie_age->oui_2 = QCOM_OUI2;
3662 qie_age->oui_3 = QCOM_OUI3;
3663 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3664 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3665#endif
3666
Jeff Johnson295189b2012-06-20 16:38:30 -07003667 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3668
3669 mgmt->frame_control |=
3670 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3671
3672#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3673 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3674 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3675 {
3676 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3677 }
3678 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3679 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3680
3681 {
3682 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3683 }
3684 else
3685 {
3686 kfree(mgmt);
3687 return NULL;
3688 }
3689#else
3690 freq = ieee80211_channel_to_frequency(chan_no);
3691#endif
3692 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003693 /*when the band is changed on the fly using the GUI, three things are done
3694 * 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)
3695 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3696 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3697 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3698 * and discards the channels correponding to previous band and calls back with zero bss results.
3699 * 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
3700 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3701 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3702 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3703 * So drop the bss and continue to next bss.
3704 */
3705 if(chan == NULL)
3706 {
3707 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3708 return NULL;
3709 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003710 /*To keep the rssi icon of the connected AP in the scan window
3711 *and the rssi icon of the wireless networks in sync
3712 * */
3713 if (( eConnectionState_Associated ==
3714 pAdapter->sessionCtx.station.conn_info.connState ) &&
3715 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3716 pAdapter->sessionCtx.station.conn_info.bssId,
3717 WNI_CFG_BSSID_LEN)))
3718 {
3719 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3720 rssi = (pAdapter->rssi * 100);
3721 }
3722 else
3723 {
3724 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3725 }
3726
3727 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3728 frame_len, rssi, GFP_KERNEL);
3729 kfree(mgmt);
3730 return bss_status;
3731}
3732
3733/*
3734 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3735 * This function is used to update the BSS data base of CFG8011
3736 */
3737struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3738 tCsrRoamInfo *pRoamInfo
3739 )
3740{
3741 tCsrRoamConnectedProfile roamProfile;
3742 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3743 struct cfg80211_bss *bss = NULL;
3744
3745 ENTER();
3746
3747 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3748 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3749
3750 if (NULL != roamProfile.pBssDesc)
3751 {
3752 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3753 &roamProfile);
3754
3755 if (NULL == bss)
3756 {
3757 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3758 __func__);
3759 }
3760
3761 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3762 }
3763 else
3764 {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3766 __func__);
3767 }
3768 return bss;
3769}
3770
3771/*
3772 * FUNCTION: wlan_hdd_cfg80211_update_bss
3773 */
3774static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3775 hdd_adapter_t *pAdapter
3776 )
3777{
3778 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3779 tCsrScanResultInfo *pScanResult;
3780 eHalStatus status = 0;
3781 tScanResultHandle pResult;
3782 struct cfg80211_bss *bss_status = NULL;
3783
3784 ENTER();
3785
3786 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3787 {
3788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3789 return -EAGAIN;
3790 }
3791
3792 /*
3793 * start getting scan results and populate cgf80211 BSS database
3794 */
3795 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3796
3797 /* no scan results */
3798 if (NULL == pResult)
3799 {
3800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3801 return status;
3802 }
3803
3804 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3805
3806 while (pScanResult)
3807 {
3808 /*
3809 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3810 * entry already exists in bss data base of cfg80211 for that
3811 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3812 * bss entry instead of cfg80211_inform_bss, But this call expects
3813 * mgmt packet as input. As of now there is no possibility to get
3814 * the mgmt(probe response) frame from PE, converting bss_desc to
3815 * ieee80211_mgmt(probe response) and passing to c
3816 * fg80211_inform_bss_frame.
3817 * */
3818
3819 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3820 &pScanResult->BssDescriptor);
3821
3822
3823 if (NULL == bss_status)
3824 {
3825 hddLog(VOS_TRACE_LEVEL_INFO,
3826 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3827 }
3828 else
3829 {
3830 cfg80211_put_bss(bss_status);
3831 }
3832
3833 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3834 }
3835
3836 sme_ScanResultPurge(hHal, pResult);
3837
3838 return 0;
3839}
3840
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003841void
3842hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3843{
3844 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003845 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3846 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3847 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003848} /****** end hddPrintMacAddr() ******/
3849
3850void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003851hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003852{
3853 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003854 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3855 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3856 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3857 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003858} /****** end hddPrintPmkId() ******/
3859
3860//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3861//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3862
3863//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3864//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3865
3866#define dump_bssid(bssid) \
3867 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003868 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3869 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3870 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003871 }
3872
3873#define dump_pmkid(pMac, pmkid) \
3874 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003875 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3876 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3877 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003878 }
3879
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003880#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003881/*
3882 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3883 * This function is used to notify the supplicant of a new PMKSA candidate.
3884 */
3885int wlan_hdd_cfg80211_pmksa_candidate_notify(
3886 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3887 int index, bool preauth )
3888{
Jeff Johnsone7245742012-09-05 17:12:55 -07003889#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003890 struct net_device *dev = pAdapter->dev;
3891
3892 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003893 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003894
3895 if( NULL == pRoamInfo )
3896 {
3897 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3898 return -EINVAL;
3899 }
3900
3901 dump_bssid(pRoamInfo->bssid);
3902 cfg80211_pmksa_candidate_notify(dev, index,
3903 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003904#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003905 return 0;
3906}
3907#endif //FEATURE_WLAN_LFR
3908
Jeff Johnson295189b2012-06-20 16:38:30 -07003909/*
3910 * FUNCTION: hdd_cfg80211_scan_done_callback
3911 * scanning callback function, called after finishing scan
3912 *
3913 */
3914static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3915 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3916{
3917 struct net_device *dev = (struct net_device *) pContext;
3918 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3919 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003920 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3921 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 struct cfg80211_scan_request *req = NULL;
3923 int ret = 0;
3924
3925 ENTER();
3926
3927 hddLog(VOS_TRACE_LEVEL_INFO,
3928 "%s called with halHandle = %p, pContext = %p,"
3929 "scanID = %d, returned status = %d\n",
3930 __func__, halHandle, pContext, (int) scanId, (int) status);
3931
3932 //Block on scan req completion variable. Can't wait forever though.
3933 ret = wait_for_completion_interruptible_timeout(
3934 &pScanInfo->scan_req_completion_event,
3935 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3936 if (!ret)
3937 {
3938 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003939 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003940 }
3941
3942 if(pScanInfo->mScanPending != VOS_TRUE)
3943 {
3944 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003945 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003946 }
3947
3948 /* Check the scanId */
3949 if (pScanInfo->scanId != scanId)
3950 {
3951 hddLog(VOS_TRACE_LEVEL_INFO,
3952 "%s called with mismatched scanId pScanInfo->scanId = %d "
3953 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3954 (int) scanId);
3955 }
3956
Jeff Johnson295189b2012-06-20 16:38:30 -07003957 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3958 pAdapter);
3959
3960 if (0 > ret)
3961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3962
3963
3964 /* If any client wait scan result through WEXT
3965 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003966 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003967 {
3968 /* The other scan request waiting for current scan finish
3969 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003970 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003972 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003973 }
3974 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003975 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003976 {
3977 struct net_device *dev = pAdapter->dev;
3978 union iwreq_data wrqu;
3979 int we_event;
3980 char *msg;
3981
3982 memset(&wrqu, '\0', sizeof(wrqu));
3983 we_event = SIOCGIWSCAN;
3984 msg = NULL;
3985 wireless_send_event(dev, we_event, &wrqu, msg);
3986 }
3987 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003988 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003989
3990 /* Get the Scan Req */
3991 req = pAdapter->request;
3992
3993 if (!req)
3994 {
3995 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003996 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003997 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003998 }
3999
4000 /*
4001 * setting up 0, just in case.
4002 */
4003 req->n_ssids = 0;
4004 req->n_channels = 0;
4005 req->ie = 0;
4006
Jeff Johnson295189b2012-06-20 16:38:30 -07004007 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004008 /* Scan is no longer pending */
4009 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004010
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004011 /*
4012 * cfg80211_scan_done informing NL80211 about completion
4013 * of scanning
4014 */
4015 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004016 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004017
Jeff Johnsone7245742012-09-05 17:12:55 -07004018allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004019 /* release the wake lock at the end of the scan*/
4020 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004021
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004022 /* Acquire wakelock to handle the case where APP's tries to suspend
4023 * immediatly after the driver gets connect request(i.e after scan)
4024 * from supplicant, this result in app's is suspending and not able
4025 * to process the connect request to AP */
4026 hdd_allow_suspend_timeout(100);
4027
Jeff Johnson295189b2012-06-20 16:38:30 -07004028 EXIT();
4029 return 0;
4030}
4031
4032/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004033 * FUNCTION: hdd_isScanAllowed
4034 * Go through each adapter and check if scan allowed
4035 *
4036 */
4037v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4038{
4039 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4040 hdd_station_ctx_t *pHddStaCtx = NULL;
4041 hdd_adapter_t *pAdapter = NULL;
4042 VOS_STATUS status = 0;
4043 v_U8_t staId = 0;
4044 v_U8_t *staMac = NULL;
4045
4046 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4047
4048 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4049 {
4050 pAdapter = pAdapterNode->pAdapter;
4051
4052 if( pAdapter )
4053 {
4054 hddLog(VOS_TRACE_LEVEL_INFO,
4055 "%s: Adapter with device mode %d exists",
4056 __func__, pAdapter->device_mode);
4057 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4058 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4059 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4060 {
4061 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4062 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4063 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4064 {
4065 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4066 hddLog(VOS_TRACE_LEVEL_ERROR,
4067 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4068 "middle of WPS/EAPOL exchange.", __func__,
4069 staMac[0], staMac[1], staMac[2],
4070 staMac[3], staMac[4], staMac[5]);
4071 return VOS_FALSE;
4072 }
4073 }
4074 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4075 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4076 {
4077 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4078 {
4079 if ((pAdapter->aStaInfo[staId].isUsed) &&
4080 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4081 {
4082 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4083
4084 hddLog(VOS_TRACE_LEVEL_ERROR,
4085 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4086 "middle of WPS/EAPOL exchange.", __func__,
4087 staMac[0], staMac[1], staMac[2],
4088 staMac[3], staMac[4], staMac[5]);
4089 return VOS_FALSE;
4090 }
4091 }
4092 }
4093 }
4094 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4095 pAdapterNode = pNext;
4096 }
4097 hddLog(VOS_TRACE_LEVEL_INFO,
4098 "%s: Scan allowed", __func__);
4099 return VOS_TRUE;
4100}
4101
4102/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004103 * FUNCTION: wlan_hdd_cfg80211_scan
4104 * this scan respond to scan trigger and update cfg80211 scan database
4105 * later, scan dump command can be used to recieve scan results
4106 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004107int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4108#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4109 struct net_device *dev,
4110#endif
4111 struct cfg80211_scan_request *request)
4112{
4113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4114 struct net_device *dev = request->wdev->netdev;
4115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004116 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4117 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4118 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4119 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4120 tCsrScanRequest scanRequest;
4121 tANI_U8 *channelList = NULL, i;
4122 v_U32_t scanId = 0;
4123 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004124 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004125#ifdef WLAN_FEATURE_P2P
4126 v_U8_t* pP2pIe = NULL;
4127#endif
4128
4129 ENTER();
4130
4131 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4132 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004133
4134 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4135 (eConnectionState_Connecting ==
4136 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
4137 {
4138 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004139 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4140 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004141 return -EBUSY;
4142 }
4143
Jeff Johnson295189b2012-06-20 16:38:30 -07004144#ifdef WLAN_BTAMP_FEATURE
4145 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004146 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004148 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004149 "%s: No scanning when AMP is on", __func__);
4150 return -EOPNOTSUPP;
4151 }
4152#endif
4153 //Scan on any other interface is not supported.
4154 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
4155 {
4156 hddLog(VOS_TRACE_LEVEL_ERROR,
4157 "%s: Not scanning on device_mode = %d",
4158 __func__, pAdapter->device_mode);
4159 return -EOPNOTSUPP;
4160 }
4161
4162 if (TRUE == pScanInfo->mScanPending)
4163 {
4164 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
4165 return -EBUSY;
4166 }
4167
4168 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4169 {
4170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4171 "%s:LOGP in Progress. Ignore!!!", __func__);
4172 return -EAGAIN;
4173 }
4174
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004175 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4176 {
4177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4178 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4179 return -EAGAIN;
4180 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004181 //Don't Allow Scan and return busy if Remain On
4182 //Channel and action frame is pending
4183 //Otherwise Cancel Remain On Channel and allow Scan
4184 //If no action frame pending
4185 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
4186 {
4187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4188 return -EBUSY;
4189 }
4190
Jeff Johnson295189b2012-06-20 16:38:30 -07004191 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4192 {
4193 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004194 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004195 return -EAGAIN;
4196 }
4197 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4198 {
4199 hddLog(VOS_TRACE_LEVEL_WARN,
4200 "%s: MAX TM Level Scan not allowed", __func__);
4201 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4202 return -EBUSY;
4203 }
4204 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4205
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004206 /* Check if scan is allowed at this point of time.
4207 */
4208 if (!hdd_isScanAllowed(pHddCtx))
4209 {
4210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4211 return -EBUSY;
4212 }
4213
Jeff Johnson295189b2012-06-20 16:38:30 -07004214 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4215
4216 if (NULL != request)
4217 {
4218 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4219 (int)request->n_ssids);
4220
4221 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4222 * Becasue of this, driver is assuming that this is not wildcard scan and so
4223 * is not aging out the scan results.
4224 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004225 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004226 {
4227 request->n_ssids = 0;
4228 }
4229
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004230 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 {
4232 tCsrSSIDInfo *SsidInfo;
4233 int j;
4234 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4235 /* Allocate num_ssid tCsrSSIDInfo structure */
4236 SsidInfo = scanRequest.SSIDs.SSIDList =
4237 ( tCsrSSIDInfo *)vos_mem_malloc(
4238 request->n_ssids*sizeof(tCsrSSIDInfo));
4239
4240 if(NULL == scanRequest.SSIDs.SSIDList)
4241 {
4242 hddLog(VOS_TRACE_LEVEL_ERROR,
4243 "memory alloc failed SSIDInfo buffer");
4244 return -ENOMEM;
4245 }
4246
4247 /* copy all the ssid's and their length */
4248 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4249 {
4250 /* get the ssid length */
4251 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4252 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4253 SsidInfo->SSID.length);
4254 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4255 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4256 j, SsidInfo->SSID.ssId);
4257 }
4258 /* set the scan type to active */
4259 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4260 }
4261 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4262 {
4263 /* set the scan type to active */
4264 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4265 }
4266 else
4267 {
4268 /*Set the scan type to default type, in this case it is ACTIVE*/
4269 scanRequest.scanType = pScanInfo->scan_mode;
4270 }
4271 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4272 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4273 }
4274 else
4275 {
4276 /* set the scan type to active */
4277 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4278 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4279
4280 /* set min and max channel time to zero */
4281 scanRequest.minChnTime = 0;
4282 scanRequest.maxChnTime = 0;
4283 }
4284
4285 /* set BSSType to default type */
4286 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4287
4288 /*TODO: scan the requested channels only*/
4289
4290 /*Right now scanning all the channels */
4291 if( request )
4292 {
4293 if( request->n_channels )
4294 {
4295 channelList = vos_mem_malloc( request->n_channels );
4296 if( NULL == channelList )
4297 {
4298 status = -ENOMEM;
4299 goto free_mem;
4300 }
4301
4302 for( i = 0 ; i < request->n_channels ; i++ )
4303 channelList[i] = request->channels[i]->hw_value;
4304 }
4305
4306 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4307 scanRequest.ChannelInfo.ChannelList = channelList;
4308
4309 /* set requestType to full scan */
4310 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004311
4312 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4313 * search (Flush on both full scan and social scan but not on single
4314 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4315 */
4316
4317 /* Supplicant does single channel scan after 8-way handshake
4318 * and in that case driver shoudnt flush scan results. If
4319 * driver flushes the scan results here and unfortunately if
4320 * the AP doesnt respond to our probe req then association
4321 * fails which is not desired
4322 */
4323
4324 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4325 {
4326 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4327 pAdapter->sessionId );
4328 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004329
4330 if( request->ie_len )
4331 {
4332 /* save this for future association (join requires this) */
4333 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4334 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4335 pScanInfo->scanAddIE.length = request->ie_len;
4336
4337 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004338 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4339 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004340 )
4341 {
4342 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4343 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4344 }
4345
4346 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4347 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4348
4349#ifdef WLAN_FEATURE_P2P
4350 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4351 request->ie_len);
4352 if (pP2pIe != NULL)
4353 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004354#ifdef WLAN_FEATURE_P2P_DEBUG
4355 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4356 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4357 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4358 {
4359 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4360 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4361 "Go nego completed to Connection is started");
4362 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4363 "for 8way Handshake");
4364 }
4365 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4366 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4367 {
4368 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4369 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4370 "Disconnected state to Connection is started");
4371 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4372 "for 4way Handshake");
4373 }
4374#endif
4375
Jeff Johnsone7245742012-09-05 17:12:55 -07004376 /* no_cck will be set during p2p find to disable 11b rates */
4377 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004378 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 hddLog(VOS_TRACE_LEVEL_INFO,
4380 "%s: This is a P2P Search", __func__);
4381 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004382
Jeff Johnsone7245742012-09-05 17:12:55 -07004383 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4384 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004385 /* set requestType to P2P Discovery */
4386 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004387 }
4388
4389 /*
4390 Skip Dfs Channel in case of P2P Search
4391 if it is set in ini file
4392 */
4393 if(cfg_param->skipDfsChnlInP2pSearch)
4394 {
4395 scanRequest.skipDfsChnlInP2pSearch = 1;
4396 }
4397 else
4398 {
4399 scanRequest.skipDfsChnlInP2pSearch = 0;
4400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004401
Jeff Johnson295189b2012-06-20 16:38:30 -07004402 }
4403 }
4404#endif
4405 }
4406 }
4407
4408 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4409
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004410 /* acquire the wakelock to avoid the apps suspend during the scan. To
4411 * address the following issues.
4412 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4413 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4414 * for long time, this result in apps running at full power for long time.
4415 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4416 * be stuck in full power because of resume BMPS
4417 */
4418 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004419
4420 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 pAdapter->sessionId, &scanRequest, &scanId,
4422 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004423
Jeff Johnson295189b2012-06-20 16:38:30 -07004424 if (eHAL_STATUS_SUCCESS != status)
4425 {
4426 hddLog(VOS_TRACE_LEVEL_ERROR,
4427 "%s: sme_ScanRequest returned error %d", __func__, status);
4428 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004429 if(eHAL_STATUS_RESOURCES == status)
4430 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004431 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 -07004432 status = -EBUSY;
4433 } else {
4434 status = -EIO;
4435 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004436 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004437 goto free_mem;
4438 }
4439
4440 pScanInfo->mScanPending = TRUE;
4441 pAdapter->request = request;
4442 pScanInfo->scanId = scanId;
4443
4444 complete(&pScanInfo->scan_req_completion_event);
4445
4446free_mem:
4447 if( scanRequest.SSIDs.SSIDList )
4448 {
4449 vos_mem_free(scanRequest.SSIDs.SSIDList);
4450 }
4451
4452 if( channelList )
4453 vos_mem_free( channelList );
4454
4455 EXIT();
4456
4457 return status;
4458}
4459
4460/*
4461 * FUNCTION: wlan_hdd_cfg80211_connect_start
4462 * This function is used to start the association process
4463 */
4464int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004465 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004466{
4467 int status = 0;
4468 hdd_wext_state_t *pWextState;
4469 v_U32_t roamId;
4470 tCsrRoamProfile *pRoamProfile;
4471 eMib_dot11DesiredBssType connectedBssType;
4472 eCsrAuthType RSNAuthType;
4473
4474 ENTER();
4475
4476 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4477
4478 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4479 {
4480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4481 return -EINVAL;
4482 }
4483
4484 pRoamProfile = &pWextState->roamProfile;
4485
4486 if (pRoamProfile)
4487 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004488 int ret = 0;
4489 hdd_station_ctx_t *pHddStaCtx;
4490 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4491 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4492
4493 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4494 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4495 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 {
4497 /* Issue disconnect to CSR */
4498 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4499 if( eHAL_STATUS_SUCCESS ==
4500 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4501 pAdapter->sessionId,
4502 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4503 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004504 ret = wait_for_completion_interruptible_timeout(
4505 &pAdapter->disconnect_comp_var,
4506 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4507 if (0 == ret)
4508 {
4509 VOS_ASSERT(0);
4510 }
4511 }
4512 }
4513 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4514 {
4515 ret = wait_for_completion_interruptible_timeout(
4516 &pAdapter->disconnect_comp_var,
4517 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4518 if (0 == ret)
4519 {
4520 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004521 }
4522 }
4523
4524 if (HDD_WMM_USER_MODE_NO_QOS ==
4525 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4526 {
4527 /*QoS not enabled in cfg file*/
4528 pRoamProfile->uapsd_mask = 0;
4529 }
4530 else
4531 {
4532 /*QoS enabled, update uapsd mask from cfg file*/
4533 pRoamProfile->uapsd_mask =
4534 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4535 }
4536
4537 pRoamProfile->SSIDs.numOfSSIDs = 1;
4538 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4539 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4540 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4541 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4542 ssid, ssid_len);
4543
4544 if (bssid)
4545 {
4546 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4547 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4548 WNI_CFG_BSSID_LEN);
4549 /* Save BSSID in seperate variable as well, as RoamProfile
4550 BSSID is getting zeroed out in the association process. And in
4551 case of join failure we should send valid BSSID to supplicant
4552 */
4553 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4554 WNI_CFG_BSSID_LEN);
4555 }
4556
4557 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4558 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4559 {
4560 /*set gen ie*/
4561 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4562 /*set auth*/
4563 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4564 }
4565 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4566 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4567 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4568 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4569 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4570 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4571 )
4572 {
4573 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4574 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4575 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4576 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4577 eCSR_AUTH_TYPE_AUTOSWITCH;
4578 pWextState->roamProfile.AuthType.authType[0] =
4579 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4580 }
4581#ifdef FEATURE_WLAN_WAPI
4582 if (pAdapter->wapi_info.nWapiMode)
4583 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004584 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004585 switch (pAdapter->wapi_info.wapiAuthMode)
4586 {
4587 case WAPI_AUTH_MODE_PSK:
4588 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004589 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004590 pAdapter->wapi_info.wapiAuthMode);
4591 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4592 break;
4593 }
4594 case WAPI_AUTH_MODE_CERT:
4595 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004596 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 pAdapter->wapi_info.wapiAuthMode);
4598 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4599 break;
4600 }
4601 } // End of switch
4602 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4603 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4604 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004605 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004606 pRoamProfile->AuthType.numEntries = 1;
4607 pRoamProfile->EncryptionType.numEntries = 1;
4608 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4609 pRoamProfile->mcEncryptionType.numEntries = 1;
4610 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4611 }
4612 }
4613#endif /* FEATURE_WLAN_WAPI */
4614 pRoamProfile->csrPersona = pAdapter->device_mode;
4615
Jeff Johnson32d95a32012-09-10 13:15:23 -07004616 if( operatingChannel )
4617 {
4618 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4619 pRoamProfile->ChannelInfo.numOfChannels = 1;
4620 }
4621
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004622 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4623 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4624 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4625 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004626 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4627 */
4628 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4629 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4630 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004631
Jeff Johnson295189b2012-06-20 16:38:30 -07004632 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4633 pAdapter->sessionId, pRoamProfile, &roamId);
4634
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004635 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304636 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4637
4638 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4640 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4641 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304642 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004643 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304644 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004645
4646 pRoamProfile->ChannelInfo.ChannelList = NULL;
4647 pRoamProfile->ChannelInfo.numOfChannels = 0;
4648
Jeff Johnson295189b2012-06-20 16:38:30 -07004649 }
4650 else
4651 {
4652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4653 return -EINVAL;
4654 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004655 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004656 return status;
4657}
4658
4659/*
4660 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4661 * This function is used to set the authentication type (OPEN/SHARED).
4662 *
4663 */
4664static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4665 enum nl80211_auth_type auth_type)
4666{
4667 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4669
4670 ENTER();
4671
4672 /*set authentication type*/
4673 switch (auth_type)
4674 {
4675 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4676 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004677#ifdef WLAN_FEATURE_VOWIFI_11R
4678 case NL80211_AUTHTYPE_FT:
4679#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004680 hddLog(VOS_TRACE_LEVEL_INFO,
4681 "%s: set authentication type to OPEN", __func__);
4682 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4683 break;
4684
4685 case NL80211_AUTHTYPE_SHARED_KEY:
4686 hddLog(VOS_TRACE_LEVEL_INFO,
4687 "%s: set authentication type to SHARED", __func__);
4688 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4689 break;
4690#ifdef FEATURE_WLAN_CCX
4691 case NL80211_AUTHTYPE_NETWORK_EAP:
4692 hddLog(VOS_TRACE_LEVEL_INFO,
4693 "%s: set authentication type to CCKM WPA", __func__);
4694 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4695 break;
4696#endif
4697
4698
4699 default:
4700 hddLog(VOS_TRACE_LEVEL_ERROR,
4701 "%s: Unsupported authentication type %d", __func__,
4702 auth_type);
4703 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4704 return -EINVAL;
4705 }
4706
4707 pWextState->roamProfile.AuthType.authType[0] =
4708 pHddStaCtx->conn_info.authType;
4709 return 0;
4710}
4711
4712/*
4713 * FUNCTION: wlan_hdd_set_akm_suite
4714 * This function is used to set the key mgmt type(PSK/8021x).
4715 *
4716 */
4717static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4718 u32 key_mgmt
4719 )
4720{
4721 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4722 ENTER();
4723
4724 /*set key mgmt type*/
4725 switch(key_mgmt)
4726 {
4727 case WLAN_AKM_SUITE_PSK:
4728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4729 __func__);
4730 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4731 break;
4732
4733 case WLAN_AKM_SUITE_8021X:
4734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4735 __func__);
4736 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4737 break;
4738#ifdef FEATURE_WLAN_CCX
4739#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4740#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4741 case WLAN_AKM_SUITE_CCKM:
4742 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4743 __func__);
4744 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4745 break;
4746#endif
4747
4748 default:
4749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4750 __func__, key_mgmt);
4751 return -EINVAL;
4752
4753 }
4754 return 0;
4755}
4756
4757/*
4758 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4759 * This function is used to set the encryption type
4760 * (NONE/WEP40/WEP104/TKIP/CCMP).
4761 */
4762static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4763 u32 cipher,
4764 bool ucast
4765 )
4766{
4767 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4768 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4770
4771 ENTER();
4772
4773 if (!cipher)
4774 {
4775 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4776 __func__, cipher);
4777 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4778 }
4779 else
4780 {
4781
4782 /*set encryption method*/
4783 switch (cipher)
4784 {
4785 case IW_AUTH_CIPHER_NONE:
4786 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4787 break;
4788
4789 case WLAN_CIPHER_SUITE_WEP40:
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_WEP40;
4793 else
4794 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4795 break;
4796
4797 case WLAN_CIPHER_SUITE_WEP104:
4798 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4799 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4800 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4801 else
4802 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4803 break;
4804
4805 case WLAN_CIPHER_SUITE_TKIP:
4806 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4807 break;
4808
4809 case WLAN_CIPHER_SUITE_CCMP:
4810 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4811 break;
4812#ifdef FEATURE_WLAN_WAPI
4813 case WLAN_CIPHER_SUITE_SMS4:
4814 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4815 break;
4816#endif
4817
4818#ifdef FEATURE_WLAN_CCX
4819 case WLAN_CIPHER_SUITE_KRK:
4820 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4821 break;
4822#endif
4823 default:
4824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4825 __func__, cipher);
4826 return -EOPNOTSUPP;
4827 }
4828 }
4829
4830 if (ucast)
4831 {
4832 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4833 __func__, encryptionType);
4834 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4835 pWextState->roamProfile.EncryptionType.numEntries = 1;
4836 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4837 encryptionType;
4838 }
4839 else
4840 {
4841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4842 __func__, encryptionType);
4843 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4844 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4845 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4846 }
4847
4848 return 0;
4849}
4850
4851
4852/*
4853 * FUNCTION: wlan_hdd_cfg80211_set_ie
4854 * This function is used to parse WPA/RSN IE's.
4855 */
4856int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4857 u8 *ie,
4858 size_t ie_len
4859 )
4860{
4861 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4862 u8 *genie = ie;
4863 v_U16_t remLen = ie_len;
4864#ifdef FEATURE_WLAN_WAPI
4865 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4866 u16 *tmp;
4867 v_U16_t akmsuiteCount;
4868 int *akmlist;
4869#endif
4870 ENTER();
4871
4872 /* clear previous assocAddIE */
4873 pWextState->assocAddIE.length = 0;
4874 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4875
4876 while (remLen >= 2)
4877 {
4878 v_U16_t eLen = 0;
4879 v_U8_t elementId;
4880 elementId = *genie++;
4881 eLen = *genie++;
4882 remLen -= 2;
4883
4884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4885 __func__, elementId, eLen);
4886
4887 switch ( elementId )
4888 {
4889 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004890 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 -07004891 {
4892 hddLog(VOS_TRACE_LEVEL_ERROR,
4893 "%s: Invalid WPA IE", __func__);
4894 return -EINVAL;
4895 }
4896 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4897 {
4898 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4899 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4900 __func__, eLen + 2);
4901
4902 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4903 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004904 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4905 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004906 VOS_ASSERT(0);
4907 return -ENOMEM;
4908 }
4909 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4910 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4911 pWextState->assocAddIE.length += eLen + 2;
4912
4913 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4914 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4915 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4916 }
4917 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4918 {
4919 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4920 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4921 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4922 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4923 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4924 }
4925#ifdef WLAN_FEATURE_P2P
4926 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4927 P2P_OUI_TYPE_SIZE))
4928 /*Consider P2P IE, only for P2P Client */
4929 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4930 {
4931 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4932 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4933 __func__, eLen + 2);
4934
4935 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4936 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004937 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4938 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004939 VOS_ASSERT(0);
4940 return -ENOMEM;
4941 }
4942 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4943 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4944 pWextState->assocAddIE.length += eLen + 2;
4945
4946 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4947 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4948 }
4949#endif
4950#ifdef WLAN_FEATURE_WFD
4951 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4952 WFD_OUI_TYPE_SIZE))
4953 /*Consider WFD IE, only for P2P Client */
4954 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4955 {
4956 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4957 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4958 __func__, eLen + 2);
4959
4960 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4961 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004962 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4963 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004964 VOS_ASSERT(0);
4965 return -ENOMEM;
4966 }
4967 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4968 // WPS IE + P2P IE + WFD IE
4969 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4970 pWextState->assocAddIE.length += eLen + 2;
4971
4972 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4973 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4974 }
4975#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004976 /* Appending HS 2.0 Indication Element in Assiciation Request */
4977 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004978 HS20_OUI_TYPE_SIZE)) )
4979 {
4980 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4981 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4982 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004983
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004984 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4985 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004986 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4987 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004988 VOS_ASSERT(0);
4989 return -ENOMEM;
4990 }
4991 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4992 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004993
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004994 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4995 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4996 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004997
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 break;
4999 case DOT11F_EID_RSN:
5000 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5001 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5002 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5003 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5004 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5005 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005006 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5007 case DOT11F_EID_EXTCAP:
5008 {
5009 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5010 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5011 __func__, eLen + 2);
5012
5013 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5014 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005015 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5016 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005017 VOS_ASSERT(0);
5018 return -ENOMEM;
5019 }
5020 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5021 pWextState->assocAddIE.length += eLen + 2;
5022
5023 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5024 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5025 break;
5026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005027#ifdef FEATURE_WLAN_WAPI
5028 case WLAN_EID_WAPI:
5029 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5030 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5031 pAdapter->wapi_info.nWapiMode);
5032 tmp = (u16 *)ie;
5033 tmp = tmp + 2; // Skip element Id and Len, Version
5034 akmsuiteCount = WPA_GET_LE16(tmp);
5035 tmp = tmp + 1;
5036 akmlist = (int *)(tmp);
5037 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5038 {
5039 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5040 }
5041 else
5042 {
5043 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5044 VOS_ASSERT(0);
5045 return -EINVAL;
5046 }
5047
5048 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5049 {
5050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005051 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5053 }
5054 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5055 {
5056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005057 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5059 }
5060 break;
5061#endif
5062 default:
5063 hddLog (VOS_TRACE_LEVEL_ERROR,
5064 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005065 /* when Unknown IE is received we should break and continue
5066 * to the next IE in the buffer instead we were returning
5067 * so changing this to break */
5068 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005069 }
5070 genie += eLen;
5071 remLen -= eLen;
5072 }
5073 EXIT();
5074 return 0;
5075}
5076
5077/*
5078 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5079 * This function is used to initialize the security
5080 * parameters during connect operation.
5081 */
5082int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5083 struct cfg80211_connect_params *req
5084 )
5085{
5086 int status = 0;
5087 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5088 ENTER();
5089
5090 /*set wpa version*/
5091 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5092
5093 if (req->crypto.wpa_versions)
5094 {
5095 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5096 && ( (req->ie_len)
5097 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5098 // Make sure that it is including a WPA IE.
5099 /* Currently NL is putting WPA version 1 even for open,
5100 * since p2p ie is also put in same buffer.
5101 * */
5102 {
5103 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5104 }
5105 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5106 {
5107 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5108 }
5109 }
5110
5111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5112 pWextState->wpaVersion);
5113
5114 /*set authentication type*/
5115 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5116
5117 if (0 > status)
5118 {
5119 hddLog(VOS_TRACE_LEVEL_ERROR,
5120 "%s: failed to set authentication type ", __func__);
5121 return status;
5122 }
5123
5124 /*set key mgmt type*/
5125 if (req->crypto.n_akm_suites)
5126 {
5127 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5128 if (0 > status)
5129 {
5130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5131 __func__);
5132 return status;
5133 }
5134 }
5135
5136 /*set pairwise cipher type*/
5137 if (req->crypto.n_ciphers_pairwise)
5138 {
5139 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5140 req->crypto.ciphers_pairwise[0], true);
5141 if (0 > status)
5142 {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 "%s: failed to set unicast cipher type", __func__);
5145 return status;
5146 }
5147 }
5148 else
5149 {
5150 /*Reset previous cipher suite to none*/
5151 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5152 if (0 > status)
5153 {
5154 hddLog(VOS_TRACE_LEVEL_ERROR,
5155 "%s: failed to set unicast cipher type", __func__);
5156 return status;
5157 }
5158 }
5159
5160 /*set group cipher type*/
5161 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5162 false);
5163
5164 if (0 > status)
5165 {
5166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5167 __func__);
5168 return status;
5169 }
5170
5171 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5172 if (req->ie_len)
5173 {
5174 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5175 if ( 0 > status)
5176 {
5177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5178 __func__);
5179 return status;
5180 }
5181 }
5182
5183 /*incase of WEP set default key information*/
5184 if (req->key && req->key_len)
5185 {
5186 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5187 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5188 )
5189 {
5190 if ( IW_AUTH_KEY_MGMT_802_1X
5191 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5192 {
5193 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5194 __func__);
5195 return -EOPNOTSUPP;
5196 }
5197 else
5198 {
5199 u8 key_len = req->key_len;
5200 u8 key_idx = req->key_idx;
5201
5202 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5203 && (CSR_MAX_NUM_KEY > key_idx)
5204 )
5205 {
5206 hddLog(VOS_TRACE_LEVEL_INFO,
5207 "%s: setting default wep key, key_idx = %hu key_len %hu",
5208 __func__, key_idx, key_len);
5209 vos_mem_copy(
5210 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5211 req->key, key_len);
5212 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5213 (u8)key_len;
5214 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5215 }
5216 }
5217 }
5218 }
5219
5220 return status;
5221}
5222
5223/*
5224 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5225 * This function is used to initialize the security
5226 * parameters during connect operation.
5227 */
5228static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5229 struct net_device *ndev,
5230 struct cfg80211_connect_params *req
5231 )
5232{
5233 int status = 0;
5234 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5235 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5236 hdd_context_t *pHddCtx = NULL;
5237
5238 ENTER();
5239
5240 hddLog(VOS_TRACE_LEVEL_INFO,
5241 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5242
5243 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5244 {
5245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5246 "%s:LOGP in Progress. Ignore!!!", __func__);
5247 return -EAGAIN;
5248 }
5249
5250#ifdef WLAN_BTAMP_FEATURE
5251 //Infra connect not supported when AMP traffic is on.
5252 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5253 {
5254 hddLog(VOS_TRACE_LEVEL_ERROR,
5255 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005256 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 }
5258#endif
5259 /*initialise security parameters*/
5260 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5261
5262 if ( 0 > status)
5263 {
5264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5265 __func__);
5266 return status;
5267 }
5268
5269 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005270 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5272 (vos_concurrent_sessions_running()))
5273 {
5274 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5275
5276 if (NULL != pVosContext)
5277 {
5278 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5279 if(NULL != pHddCtx)
5280 {
5281 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5282 }
5283 }
5284 }
5285
Mohit Khanna765234a2012-09-11 15:08:35 -07005286 if ( req->channel )
5287 {
5288 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5289 req->ssid_len, req->bssid,
5290 req->channel->hw_value);
5291 }
5292 else
5293 {
5294 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5295 req->ssid_len, req->bssid,
5296 0);
5297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005298
5299 if (0 > status)
5300 {
5301 //ReEnable BMPS if disabled
5302 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5303 (NULL != pHddCtx))
5304 {
5305 //ReEnable Bmps and Imps back
5306 hdd_enable_bmps_imps(pHddCtx);
5307 }
5308
5309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5310 return status;
5311 }
5312 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5313 EXIT();
5314 return status;
5315}
5316
5317
5318/*
5319 * FUNCTION: wlan_hdd_cfg80211_disconnect
5320 * This function is used to issue a disconnect request to SME
5321 */
5322static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5323 struct net_device *dev,
5324 u16 reason
5325 )
5326{
5327 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5328 tCsrRoamProfile *pRoamProfile =
5329 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5330 int status = 0;
5331 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5332
5333 ENTER();
5334
5335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5336 __func__,pAdapter->device_mode);
5337
5338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5339 __func__, reason);
5340
5341 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5342 {
5343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5344 "%s:LOGP in Progress. Ignore!!!",__func__);
5345 return -EAGAIN;
5346 }
5347 if (NULL != pRoamProfile)
5348 {
5349 /*issue disconnect request to SME, if station is in connected state*/
5350 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5351 {
5352 eCsrRoamDisconnectReason reasonCode =
5353 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5354 switch(reason)
5355 {
5356 case WLAN_REASON_MIC_FAILURE:
5357 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5358 break;
5359
5360 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5361 case WLAN_REASON_DISASSOC_AP_BUSY:
5362 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5363 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5364 break;
5365
5366 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5367 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5368 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5369 break;
5370
5371 case WLAN_REASON_DEAUTH_LEAVING:
5372 default:
5373 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5374 break;
5375 }
5376 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5377 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5378 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5379
5380 /*issue disconnect*/
5381 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5382 pAdapter->sessionId, reasonCode);
5383
5384 if ( 0 != status)
5385 {
5386 hddLog(VOS_TRACE_LEVEL_ERROR,
5387 "%s csrRoamDisconnect failure, returned %d \n",
5388 __func__, (int)status );
5389 return -EINVAL;
5390 }
5391
5392 wait_for_completion_interruptible_timeout(
5393 &pAdapter->disconnect_comp_var,
5394 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5395
5396
5397 /*stop tx queues*/
5398 netif_tx_disable(dev);
5399 netif_carrier_off(dev);
5400 }
5401 }
5402 else
5403 {
5404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5405 }
5406
5407 return status;
5408}
5409
5410/*
5411 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5412 * This function is used to initialize the security
5413 * settings in IBSS mode.
5414 */
5415static int wlan_hdd_cfg80211_set_privacy_ibss(
5416 hdd_adapter_t *pAdapter,
5417 struct cfg80211_ibss_params *params
5418 )
5419{
5420 int status = 0;
5421 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5422 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5423 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5424
5425 ENTER();
5426
5427 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5428
5429 if (params->ie_len && ( NULL != params->ie) )
5430 {
5431 if (WLAN_EID_RSN == params->ie[0])
5432 {
5433 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5434 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5435 }
5436 else
5437 {
5438 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5439 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5440 }
5441 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5442
5443 if (0 > status)
5444 {
5445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5446 __func__);
5447 return status;
5448 }
5449 }
5450
5451 pWextState->roamProfile.AuthType.authType[0] =
5452 pHddStaCtx->conn_info.authType =
5453 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5454
5455 if (params->privacy)
5456 {
5457 /* Security enabled IBSS, At this time there is no information available
5458 * about the security paramters, so initialise the encryption type to
5459 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5460 * The correct security parameters will be updated later in
5461 * wlan_hdd_cfg80211_add_key */
5462 /* Hal expects encryption type to be set inorder
5463 *enable privacy bit in beacons */
5464
5465 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5466 }
5467
5468 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5469 pWextState->roamProfile.EncryptionType.numEntries = 1;
5470 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5471
5472 return status;
5473}
5474
5475/*
5476 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5477 * This function is used to create/join an IBSS
5478 */
5479static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5480 struct net_device *dev,
5481 struct cfg80211_ibss_params *params
5482 )
5483{
5484 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5485 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5486 tCsrRoamProfile *pRoamProfile;
5487 int status;
5488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5489
5490 ENTER();
5491
5492 hddLog(VOS_TRACE_LEVEL_INFO,
5493 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5494
5495 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5496 {
5497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5498 "%s:LOGP in Progress. Ignore!!!", __func__);
5499 return -EAGAIN;
5500 }
5501
5502 if (NULL == pWextState)
5503 {
5504 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5505 __func__);
5506 return -EIO;
5507 }
5508
5509 pRoamProfile = &pWextState->roamProfile;
5510
5511 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5512 {
5513 hddLog (VOS_TRACE_LEVEL_ERROR,
5514 "%s Interface type is not set to IBSS \n", __func__);
5515 return -EINVAL;
5516 }
5517
5518 /* Set Channel */
5519 if (NULL != params->channel)
5520 {
5521 u8 channelNum;
5522 if (IEEE80211_BAND_5GHZ == params->channel->band)
5523 {
5524 hddLog(VOS_TRACE_LEVEL_ERROR,
5525 "%s: IBSS join is called with unsupported band %d",
5526 __func__, params->channel->band);
5527 return -EOPNOTSUPP;
5528 }
5529
5530 /* Get channel number */
5531 channelNum =
5532 ieee80211_frequency_to_channel(params->channel->center_freq);
5533
5534 /*TODO: use macro*/
5535 if (14 >= channelNum)
5536 {
5537 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5538 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5539 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5540 int indx;
5541
5542 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5543 validChan, &numChans))
5544 {
5545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5546 __func__);
5547 return -EOPNOTSUPP;
5548 }
5549
5550 for (indx = 0; indx < numChans; indx++)
5551 {
5552 if (channelNum == validChan[indx])
5553 {
5554 break;
5555 }
5556 }
5557 if (indx >= numChans)
5558 {
5559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5560 __func__, channelNum);
5561 return -EINVAL;
5562 }
5563 /* Set the Operational Channel */
5564 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5565 channelNum);
5566 pRoamProfile->ChannelInfo.numOfChannels = 1;
5567 pHddStaCtx->conn_info.operationChannel = channelNum;
5568 pRoamProfile->ChannelInfo.ChannelList =
5569 &pHddStaCtx->conn_info.operationChannel;
5570 }
5571 else
5572 {
5573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5574 __func__, channelNum);
5575 return -EINVAL;
5576 }
5577 }
5578
5579 /* Initialize security parameters */
5580 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5581 if (status < 0)
5582 {
5583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5584 __func__);
5585 return status;
5586 }
5587
5588 /* Issue connect start */
5589 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005590 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005591
5592 if (0 > status)
5593 {
5594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5595 return status;
5596 }
5597
5598 return 0;
5599}
5600
5601/*
5602 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5603 * This function is used to leave an IBSS
5604 */
5605static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5606 struct net_device *dev
5607 )
5608{
5609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5610 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5611 tCsrRoamProfile *pRoamProfile;
5612
5613 ENTER();
5614
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005615 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5616 {
5617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5618 "%s:LOGP in Progress. Ignore!!!", __func__);
5619 return -EAGAIN;
5620 }
5621
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5623 if (NULL == pWextState)
5624 {
5625 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5626 __func__);
5627 return -EIO;
5628 }
5629
5630 pRoamProfile = &pWextState->roamProfile;
5631
5632 /* Issue disconnect only if interface type is set to IBSS */
5633 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5634 {
5635 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5636 __func__);
5637 return -EINVAL;
5638 }
5639
5640 /* Issue Disconnect request */
5641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5642 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5643 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5644
5645 return 0;
5646}
5647
5648/*
5649 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5650 * This function is used to set the phy parameters
5651 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5652 */
5653static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5654 u32 changed)
5655{
5656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5657 tHalHandle hHal = pHddCtx->hHal;
5658
5659 ENTER();
5660
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005661 if ( pHddCtx->isLogpInProgress )
5662 {
5663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5664 "%s:LOGP in Progress. Ignore!!!", __func__);
5665 return -EAGAIN;
5666 }
5667
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5669 {
5670 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5671 WNI_CFG_RTS_THRESHOLD_STAMAX :
5672 wiphy->rts_threshold;
5673
5674 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5675 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5676 {
5677 hddLog(VOS_TRACE_LEVEL_ERROR,
5678 "%s: Invalid RTS Threshold value %hu",
5679 __func__, rts_threshold);
5680 return -EINVAL;
5681 }
5682
5683 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5684 rts_threshold, ccmCfgSetCallback,
5685 eANI_BOOLEAN_TRUE))
5686 {
5687 hddLog(VOS_TRACE_LEVEL_ERROR,
5688 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5689 __func__, rts_threshold);
5690 return -EIO;
5691 }
5692
5693 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5694 rts_threshold);
5695 }
5696
5697 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5698 {
5699 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5700 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5701 wiphy->frag_threshold;
5702
5703 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5704 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5705 {
5706 hddLog(VOS_TRACE_LEVEL_ERROR,
5707 "%s: Invalid frag_threshold value %hu", __func__,
5708 frag_threshold);
5709 return -EINVAL;
5710 }
5711
5712 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5713 frag_threshold, ccmCfgSetCallback,
5714 eANI_BOOLEAN_TRUE))
5715 {
5716 hddLog(VOS_TRACE_LEVEL_ERROR,
5717 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5718 __func__, frag_threshold);
5719 return -EIO;
5720 }
5721
5722 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5723 frag_threshold);
5724 }
5725
5726 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5727 || (changed & WIPHY_PARAM_RETRY_LONG))
5728 {
5729 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5730 wiphy->retry_short :
5731 wiphy->retry_long;
5732
5733 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5734 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5735 {
5736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5737 __func__, retry_value);
5738 return -EINVAL;
5739 }
5740
5741 if (changed & WIPHY_PARAM_RETRY_SHORT)
5742 {
5743 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5744 retry_value, ccmCfgSetCallback,
5745 eANI_BOOLEAN_TRUE))
5746 {
5747 hddLog(VOS_TRACE_LEVEL_ERROR,
5748 "%s: ccmCfgSetInt failed for long retry count %hu",
5749 __func__, retry_value);
5750 return -EIO;
5751 }
5752 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5753 __func__, retry_value);
5754 }
5755 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5756 {
5757 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5758 retry_value, ccmCfgSetCallback,
5759 eANI_BOOLEAN_TRUE))
5760 {
5761 hddLog(VOS_TRACE_LEVEL_ERROR,
5762 "%s: ccmCfgSetInt failed for short retry count %hu",
5763 __func__, retry_value);
5764 return -EIO;
5765 }
5766 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5767 __func__, retry_value);
5768 }
5769 }
5770
5771 return 0;
5772}
5773
5774/*
5775 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5776 * This function is used to set the txpower
5777 */
5778static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5779#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5780 enum tx_power_setting type,
5781#else
5782 enum nl80211_tx_power_setting type,
5783#endif
5784 int dbm)
5785{
5786 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5787 tHalHandle hHal = pHddCtx->hHal;
5788 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5789 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5790
5791 ENTER();
5792
5793 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5794 dbm, ccmCfgSetCallback,
5795 eANI_BOOLEAN_TRUE))
5796 {
5797 hddLog(VOS_TRACE_LEVEL_ERROR,
5798 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5799 return -EIO;
5800 }
5801
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005802 if ( pHddCtx->isLogpInProgress )
5803 {
5804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5805 "%s:LOGP in Progress. Ignore!!!", __func__);
5806 return -EAGAIN;
5807 }
5808
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5810 dbm);
5811
5812 switch(type)
5813 {
5814 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5815 /* Fall through */
5816 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5817 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5818 {
5819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5820 __func__);
5821 return -EIO;
5822 }
5823 break;
5824 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5826 __func__);
5827 return -EOPNOTSUPP;
5828 break;
5829 default:
5830 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5831 __func__, type);
5832 return -EIO;
5833 }
5834
5835 return 0;
5836}
5837
5838/*
5839 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5840 * This function is used to read the txpower
5841 */
5842static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5843{
5844
5845 hdd_adapter_t *pAdapter;
5846 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5847
Jeff Johnsone7245742012-09-05 17:12:55 -07005848 ENTER();
5849
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 if (NULL == pHddCtx)
5851 {
5852 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5853 *dbm = 0;
5854 return -ENOENT;
5855 }
5856
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005857 if ( pHddCtx->isLogpInProgress )
5858 {
5859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5860 "%s:LOGP in Progress. Ignore!!!", __func__);
5861 return -EAGAIN;
5862 }
5863
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5865 if (NULL == pAdapter)
5866 {
5867 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5868 return -ENOENT;
5869 }
5870
5871 wlan_hdd_get_classAstats(pAdapter);
5872 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5873
Jeff Johnsone7245742012-09-05 17:12:55 -07005874 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 return 0;
5876}
5877
5878static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5879 u8* mac, struct station_info *sinfo)
5880{
5881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5882 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5883 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5884 tANI_U8 rate_flags;
5885
5886 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5887 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5888 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5889
5890 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5891 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5892 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5893 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5894 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5895 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5896 tANI_U16 maxRate = 0;
5897 tANI_U16 myRate;
5898 tANI_U16 currentRate = 0;
5899 tANI_U8 maxSpeedMCS = 0;
5900 tANI_U8 maxMCSIdx = 0;
5901 tANI_U8 rateFlag = 1;
5902 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005903 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005904
Jeff Johnsone7245742012-09-05 17:12:55 -07005905 ENTER();
5906
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5908 (0 == ssidlen))
5909 {
5910 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5911 " Invalid ssidlen, %d", __func__, ssidlen);
5912 /*To keep GUI happy*/
5913 return 0;
5914 }
5915
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005916 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5917 {
5918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5919 "%s:LOGP in Progress. Ignore!!!", __func__);
5920 return -EAGAIN;
5921 }
5922
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5924 sinfo->filled |= STATION_INFO_SIGNAL;
5925
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005926 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5928
5929 //convert to the UI units of 100kbps
5930 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5931
5932#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005933 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 -07005934 sinfo->signal,
5935 pCfg->reportMaxLinkSpeed,
5936 myRate,
5937 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005938 (int) pCfg->linkSpeedRssiMid,
5939 (int) pCfg->linkSpeedRssiLow,
5940 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005941#endif //LINKSPEED_DEBUG_ENABLED
5942
5943 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5944 {
5945 // we do not want to necessarily report the current speed
5946 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5947 {
5948 // report the max possible speed
5949 rssidx = 0;
5950 }
5951 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5952 {
5953 // report the max possible speed with RSSI scaling
5954 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5955 {
5956 // report the max possible speed
5957 rssidx = 0;
5958 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005959 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 {
5961 // report middle speed
5962 rssidx = 1;
5963 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005964 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5965 {
5966 // report middle speed
5967 rssidx = 2;
5968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 else
5970 {
5971 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005972 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 }
5974 }
5975 else
5976 {
5977 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5978 hddLog(VOS_TRACE_LEVEL_ERROR,
5979 "%s: Invalid value for reportMaxLinkSpeed: %u",
5980 __func__, pCfg->reportMaxLinkSpeed);
5981 rssidx = 0;
5982 }
5983
5984 maxRate = 0;
5985
5986 /* Get Basic Rate Set */
5987 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5988 for (i = 0; i < ORLeng; i++)
5989 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005990 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 {
5992 /* Validate Rate Set */
5993 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5994 {
5995 currentRate = supported_data_rate[j].supported_rate[rssidx];
5996 break;
5997 }
5998 }
5999 /* Update MAX rate */
6000 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6001 }
6002
6003 /* Get Extended Rate Set */
6004 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
6005 for (i = 0; i < ERLeng; i++)
6006 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006007 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 {
6009 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6010 {
6011 currentRate = supported_data_rate[j].supported_rate[rssidx];
6012 break;
6013 }
6014 }
6015 /* Update MAX rate */
6016 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6017 }
6018
6019 /* Get MCS Rate Set -- but only if we are connected at MCS
6020 rates or if we are always reporting max speed or if we have
6021 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006022 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006023 {
6024 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
6025 rateFlag = 0;
6026 if (rate_flags & eHAL_TX_RATE_HT40)
6027 {
6028 rateFlag |= 1;
6029 }
6030 if (rate_flags & eHAL_TX_RATE_SGI)
6031 {
6032 rateFlag |= 2;
6033 }
6034
6035 for (i = 0; i < MCSLeng; i++)
6036 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006037 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6038 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 {
6040 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6041 {
6042 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6043 break;
6044 }
6045 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006046 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 {
6048 maxRate = currentRate;
6049 maxSpeedMCS = 1;
6050 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6051 }
6052 }
6053 }
6054
6055 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006056 if (((maxRate < myRate) && (0 == rssidx)) ||
6057 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 {
6059 maxRate = myRate;
6060 if (rate_flags & eHAL_TX_RATE_LEGACY)
6061 {
6062 maxSpeedMCS = 0;
6063 }
6064 else
6065 {
6066 maxSpeedMCS = 1;
6067 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6068 }
6069 }
6070
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006071 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 {
6073 sinfo->txrate.legacy = maxRate;
6074#ifdef LINKSPEED_DEBUG_ENABLED
6075 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6076#endif //LINKSPEED_DEBUG_ENABLED
6077 }
6078 else
6079 {
6080 sinfo->txrate.mcs = maxMCSIdx;
6081 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6082 if (rate_flags & eHAL_TX_RATE_SGI)
6083 {
6084 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6085 }
6086 if (rate_flags & eHAL_TX_RATE_HT40)
6087 {
6088 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6089 }
6090#ifdef LINKSPEED_DEBUG_ENABLED
6091 pr_info("Reporting MCS rate %d flags %x\n",
6092 sinfo->txrate.mcs,
6093 sinfo->txrate.flags );
6094#endif //LINKSPEED_DEBUG_ENABLED
6095 }
6096 }
6097 else
6098 {
6099 // report current rate instead of max rate
6100
6101 if (rate_flags & eHAL_TX_RATE_LEGACY)
6102 {
6103 //provide to the UI in units of 100kbps
6104 sinfo->txrate.legacy = myRate;
6105#ifdef LINKSPEED_DEBUG_ENABLED
6106 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6107#endif //LINKSPEED_DEBUG_ENABLED
6108 }
6109 else
6110 {
6111 //must be MCS
6112 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6113 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6114 if (rate_flags & eHAL_TX_RATE_SGI)
6115 {
6116 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6117 }
6118 if (rate_flags & eHAL_TX_RATE_HT40)
6119 {
6120 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6121 }
6122#ifdef LINKSPEED_DEBUG_ENABLED
6123 pr_info("Reporting actual MCS rate %d flags %x\n",
6124 sinfo->txrate.mcs,
6125 sinfo->txrate.flags );
6126#endif //LINKSPEED_DEBUG_ENABLED
6127 }
6128 }
6129 sinfo->filled |= STATION_INFO_TX_BITRATE;
6130
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006131 sinfo->tx_packets =
6132 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6133 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6134 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6135 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6136
6137 sinfo->tx_retries =
6138 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6139 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6140 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6141 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6142
6143 sinfo->tx_failed =
6144 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6145 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6146 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6147 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6148
6149 sinfo->filled |=
6150 STATION_INFO_TX_PACKETS |
6151 STATION_INFO_TX_RETRIES |
6152 STATION_INFO_TX_FAILED;
6153
6154 EXIT();
6155 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006156}
6157
6158static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6159 struct net_device *dev, bool mode, v_SINT_t timeout)
6160{
6161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6162 VOS_STATUS vos_status;
6163
Jeff Johnsone7245742012-09-05 17:12:55 -07006164 ENTER();
6165
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 if (NULL == pAdapter)
6167 {
6168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6169 return -ENODEV;
6170 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006171 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6172 {
6173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6174 "%s:LOGP in Progress. Ignore!!!", __func__);
6175 return -EAGAIN;
6176 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006177
6178 /**The get power cmd from the supplicant gets updated by the nl only
6179 *on successful execution of the function call
6180 *we are oppositely mapped w.r.t mode in the driver
6181 **/
6182 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6183
Jeff Johnsone7245742012-09-05 17:12:55 -07006184 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 if (VOS_STATUS_E_FAILURE == vos_status)
6186 {
6187 return -EINVAL;
6188 }
6189 return 0;
6190}
6191
6192
6193#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6194static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6195 struct net_device *netdev,
6196 u8 key_index)
6197{
Jeff Johnsone7245742012-09-05 17:12:55 -07006198 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 return 0;
6200}
6201#endif //LINUX_VERSION_CODE
6202
6203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6204static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6205 struct net_device *dev,
6206 struct ieee80211_txq_params *params)
6207{
Jeff Johnsone7245742012-09-05 17:12:55 -07006208 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 return 0;
6210}
6211#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6212static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6213 struct ieee80211_txq_params *params)
6214{
Jeff Johnsone7245742012-09-05 17:12:55 -07006215 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 return 0;
6217}
6218#endif //LINUX_VERSION_CODE
6219
6220static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6221 struct net_device *dev, u8 *mac)
6222{
6223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006224 VOS_STATUS vos_status;
6225 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006226
Jeff Johnsone7245742012-09-05 17:12:55 -07006227 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6229 {
6230 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6231 return -EINVAL;
6232 }
6233
6234 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6235 {
6236 hddLog( LOGE,
6237 "%s: Wlan Load/Unload is in progress", __func__);
6238 return -EBUSY;
6239 }
6240
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006241 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6242 {
6243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6244 "%s:LOGP in Progress. Ignore!!!", __func__);
6245 return -EAGAIN;
6246 }
6247
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6249#ifdef WLAN_FEATURE_P2P
6250 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6251#endif
6252 )
6253 {
6254 if( NULL == mac )
6255 {
6256 v_U16_t i;
6257 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6258 {
6259 if(pAdapter->aStaInfo[i].isUsed)
6260 {
6261 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6262 hddLog(VOS_TRACE_LEVEL_INFO,
6263 "%s: Delete STA with MAC::"
6264 "%02x:%02x:%02x:%02x:%02x:%02x",
6265 __func__,
6266 macAddr[0], macAddr[1], macAddr[2],
6267 macAddr[3], macAddr[4], macAddr[5]);
6268 hdd_softap_sta_deauth(pAdapter, macAddr);
6269 }
6270 }
6271 }
6272 else
6273 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006274
6275 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6276 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6277 {
6278 hddLog(VOS_TRACE_LEVEL_INFO,
6279 "%s: Skip this DEL STA as this is not used::"
6280 "%02x:%02x:%02x:%02x:%02x:%02x",
6281 __func__,
6282 mac[0], mac[1], mac[2],
6283 mac[3], mac[4], mac[5]);
6284 return -ENOENT;
6285 }
6286
6287 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6288 {
6289 hddLog(VOS_TRACE_LEVEL_INFO,
6290 "%s: Skip this DEL STA as deauth is in progress::"
6291 "%02x:%02x:%02x:%02x:%02x:%02x",
6292 __func__,
6293 mac[0], mac[1], mac[2],
6294 mac[3], mac[4], mac[5]);
6295 return -ENOENT;
6296 }
6297
6298 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6299
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 hddLog(VOS_TRACE_LEVEL_INFO,
6301 "%s: Delete STA with MAC::"
6302 "%02x:%02x:%02x:%02x:%02x:%02x",
6303 __func__,
6304 mac[0], mac[1], mac[2],
6305 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006306
6307 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6308 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6309 {
6310 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6311 hddLog(VOS_TRACE_LEVEL_INFO,
6312 "%s: STA removal failed for ::"
6313 "%02x:%02x:%02x:%02x:%02x:%02x",
6314 __func__,
6315 mac[0], mac[1], mac[2],
6316 mac[3], mac[4], mac[5]);
6317 return -ENOENT;
6318 }
6319
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 }
6321 }
6322
6323 EXIT();
6324
6325 return 0;
6326}
6327
6328static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6329 struct net_device *dev, u8 *mac, struct station_parameters *params)
6330{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006331#ifdef FEATURE_WLAN_TDLS
6332 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6333 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6334 u32 mask, set;
6335 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006336 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006337
6338 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6339 {
6340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6341 "Invalid arguments");
6342 return -EINVAL;
6343 }
6344
6345 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6346 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6347 {
6348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6349 "TDLS Disabled in INI OR not enabled in FW.\
6350 Cannot process TDLS commands \n");
6351 return -ENOTSUPP;
6352 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006353 /* first to check if we reached to maximum supported TDLS peer.
6354 TODO: for now, return -EPERM looks working fine,
6355 but need to check if any other errno fit into this category.*/
6356 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6357 {
6358 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6359 "%s: TDLS Max peer already connected. Request declined. \n",
6360 __func__);
6361 return -EPERM;
6362 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006363
6364 mask = params->sta_flags_mask;
6365
6366 set = params->sta_flags_set;
6367
6368
Lee Hoonkic1262f22013-01-24 21:59:00 -08006369 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6370 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006371
6372 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6373 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6375 "Add TDLS peer");
6376
6377
6378 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6379 pAdapter->sessionId, mac);
6380
6381 if (VOS_STATUS_SUCCESS != status) {
6382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6383 "%s: sme_AddTdlsPeerSta failed!", __func__);
6384 }
6385 }
6386 }
6387#endif
6388
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 return 0;
6390}
6391
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006392
6393#ifdef FEATURE_WLAN_LFR
6394static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006395 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006396{
6397#define MAX_PMKSAIDS_IN_CACHE 8
6398 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006399 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006400 tANI_U32 j=0;
6401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6402 tHalHandle halHandle;
6403 eHalStatus result;
6404 tANI_U8 BSSIDMatched = 0;
6405
Jeff Johnsone7245742012-09-05 17:12:55 -07006406 ENTER();
6407
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006408 // Validate pAdapter
6409 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6410 {
6411 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6412 return -EINVAL;
6413 }
6414
6415 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6416 {
6417 hddLog( LOGE,
6418 "%s: Wlan Load/Unload is in progress", __func__);
6419 return -EBUSY;
6420 }
6421
6422 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6423 {
6424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6425 "%s:LOGP in Progress. Ignore!!!", __func__);
6426 return -EAGAIN;
6427 }
6428
6429 // Retrieve halHandle
6430 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6431
6432 for (j = 0; j < i; j++)
6433 {
6434 if(vos_mem_compare(PMKIDCache[j].BSSID,
6435 pmksa->bssid, WNI_CFG_BSSID_LEN))
6436 {
6437 /* BSSID matched previous entry. Overwrite it. */
6438 BSSIDMatched = 1;
6439 vos_mem_copy(PMKIDCache[j].BSSID,
6440 pmksa->bssid, WNI_CFG_BSSID_LEN);
6441 vos_mem_copy(PMKIDCache[j].PMKID,
6442 pmksa->pmkid,
6443 CSR_RSN_PMKID_SIZE);
6444 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006445 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006446 dump_bssid(pmksa->bssid);
6447 dump_pmkid(halHandle, pmksa->pmkid);
6448 break;
6449 }
6450 }
6451
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006452 /* Check we compared all entries,if then take the first slot now */
6453 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6454
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006455 if (!BSSIDMatched)
6456 {
6457 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6458 vos_mem_copy(PMKIDCache[i].BSSID,
6459 pmksa->bssid, ETHER_ADDR_LEN);
6460 vos_mem_copy(PMKIDCache[i].PMKID,
6461 pmksa->pmkid,
6462 CSR_RSN_PMKID_SIZE);
6463 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006464 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006465 dump_bssid(pmksa->bssid);
6466 dump_pmkid(halHandle, pmksa->pmkid);
6467 // Increment the HDD Local Cache index
6468 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6469 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6470 }
6471
6472
6473 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6474 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006475 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006476 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006477 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006478 // Finally set the PMKSA ID Cache in CSR
6479 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6480 PMKIDCache,
6481 i );
6482 return 0;
6483}
6484
6485
6486static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006487 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006488{
Jeff Johnsone7245742012-09-05 17:12:55 -07006489 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006490 // TODO: Implement this later.
6491 return 0;
6492}
6493
6494static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6495{
Jeff Johnsone7245742012-09-05 17:12:55 -07006496 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006497 // TODO: Implement this later.
6498 return 0;
6499}
6500#endif
6501
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006502#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6503static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6504 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6505{
6506 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6507 hdd_station_ctx_t *pHddStaCtx;
6508
6509 if (NULL == pAdapter)
6510 {
6511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6512 return -ENODEV;
6513 }
6514
6515 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6516
6517 // Added for debug on reception of Re-assoc Req.
6518 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6519 {
6520 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6521 ftie->ie_len);
6522 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6523 }
6524
6525#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6526 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6527 ftie->ie_len);
6528#endif
6529
6530 // Pass the received FT IEs to SME
6531 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6532 ftie->ie_len);
6533 return 0;
6534}
6535#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006536
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006537#ifdef FEATURE_WLAN_TDLS
6538static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6539 u8 *peer, u8 action_code, u8 dialog_token,
6540 u16 status_code, const u8 *buf, size_t len)
6541{
6542
6543 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6544 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006545 u8 peerMac[6];
6546 VOS_STATUS status;
Hoonki Leea34dd892013-02-05 22:56:02 -08006547 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006548
6549 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6550 {
6551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6552 "Invalid arguments");
6553 return -EINVAL;
6554 }
6555
6556 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6557 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6558 {
6559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6560 "TDLS Disabled in INI OR not enabled in FW.\
6561 Cannot process TDLS commands \n");
6562 return -ENOTSUPP;
6563 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006564
6565 if(SIR_MAC_TDLS_SETUP_REQ == action_code ||
6566 SIR_MAC_TDLS_SETUP_RSP == action_code )
6567 {
6568 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6569 {
6570 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6571 we return error code at 'add_station()'. Hence we have this
6572 check again in addtion to add_station().
6573 Anyway, there is no hard to double-check. */
6574 if(SIR_MAC_TDLS_SETUP_REQ == action_code)
6575 {
6576 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6577 "%s: TDLS Max peer already connected. Request declined. \n",
6578 __func__);
6579 return -EPERM;
6580 }
6581 else
6582 {
6583 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6584 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6585 "%s: TDLS Max peer already connected send response status %d \n",
6586 __func__,status_code);
6587 }
6588 }
6589 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006590 vos_mem_copy( peerMac, peer, 6);
6591
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006592#ifdef WLAN_FEATURE_TDLS_DEBUG
6593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6594 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6595 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6596 action_code, dialog_token, status_code, len);
6597#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006598
Hoonki Leea34dd892013-02-05 22:56:02 -08006599 /*Except teardown responder will not be used so just make 0*/
6600 responder = 0;
6601 if(SIR_MAC_TDLS_TEARDOWN == action_code)
6602 {
6603 responder = wlan_hdd_tdls_get_responder(peerMac);
6604 if(-1 == responder)
6605 {
6606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6607 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6608 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6609 dialog_token, status_code, len);
6610 return -EPERM;
6611 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006612 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006613
6614 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006615 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006616
6617 if (VOS_STATUS_SUCCESS != status) {
6618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6619 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6620 }
6621
Hoonki Leea34dd892013-02-05 22:56:02 -08006622 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6623 {
6624 wlan_hdd_tdls_set_responder(peerMac, TRUE);
6625 }
6626 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6627 {
6628 wlan_hdd_tdls_set_responder(peerMac, FALSE);
6629 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006630
6631 return 0;
6632}
6633
6634static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6635 u8 *peer, enum nl80211_tdls_operation oper)
6636{
6637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6638 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006639#ifdef WLAN_FEATURE_TDLS_DEBUG
6640 const char *tdls_oper_str[]= {
6641 "NL80211_TDLS_DISCOVERY_REQ",
6642 "NL80211_TDLS_SETUP",
6643 "NL80211_TDLS_TEARDOWN",
6644 "NL80211_TDLS_ENABLE_LINK",
6645 "NL80211_TDLS_DISABLE_LINK",
6646 "NL80211_TDLS_UNKONW_OPER"};
6647#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006648
6649 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6650 {
6651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6652 "Invalid arguments");
6653 return -EINVAL;
6654 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006655
6656#ifdef WLAN_FEATURE_TDLS_DEBUG
6657 if((int)oper > 4)
6658 oper = 5;
6659
6660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6661 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6662 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6663 tdls_oper_str[(int)oper]);
6664#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006665
6666 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006667 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006668 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006670 "TDLS Disabled in INI OR not enabled in FW.\
6671 Cannot process TDLS commands \n");
6672 return -ENOTSUPP;
6673 }
6674
6675 switch (oper) {
6676 case NL80211_TDLS_ENABLE_LINK:
6677 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006678 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Hoonki Lee387663d2013-02-05 18:08:43 -08006679 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006680 VOS_STATUS status;
6681
6682 if (peer) {
Hoonki Lee387663d2013-02-05 18:08:43 -08006683 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006684
6685 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006686 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006687 __func__, peer[0], peer[1],
6688 peer[2], peer[3],
6689 peer[4], peer[5] );
6690
Hoonki Lee387663d2013-02-05 18:08:43 -08006691 if ( NULL == pTdlsPeer ) {
6692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6693 __func__, peer[0], peer[1],
6694 peer[2], peer[3],
6695 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006696 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006697 }
6698
Hoonki Lee387663d2013-02-05 18:08:43 -08006699 status = WLANTL_ChangeSTAState( pVosContext, pTdlsPeer->staId,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006700 WLANTL_STA_AUTHENTICATED );
6701
Hoonki Leef63df0d2013-01-16 19:29:14 -08006702 //This can fail only if the staId is not registered yet with TL
6703 //return -EINVAL in such case.
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006704 if (0 != status) {
6705 hddLog(VOS_TRACE_LEVEL_ERROR,
6706 "%s: WLANTL_ChangeSTAState failed, returned %d",
6707 __func__, status);
Hoonki Leef63df0d2013-01-16 19:29:14 -08006708 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006709 }
Hoonki Leef63df0d2013-01-16 19:29:14 -08006710
Hoonki Lee387663d2013-02-05 18:08:43 -08006711 wlan_hdd_tdls_set_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Chilam NG571c65a2013-01-19 12:27:36 +05306712
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006713 } else {
6714 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6715 }
6716 }
6717 break;
6718 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006719 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006720 if(NULL != wlan_hdd_tdls_find_peer(peer))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006721 {
6722 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6723 pAdapter->sessionId, peer );
6724 }
6725 else
6726 {
6727 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6728 "%s: TDLS Peer Station doesn't exist \n",__func__);
6729 }
6730 return 0;
6731 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006732 case NL80211_TDLS_TEARDOWN:
6733 case NL80211_TDLS_SETUP:
6734 case NL80211_TDLS_DISCOVERY_REQ:
6735 /* We don't support in-driver setup/teardown/discovery */
6736 return -ENOTSUPP;
6737 default:
6738 return -ENOTSUPP;
6739 }
6740 return 0;
6741}
Chilam NG571c65a2013-01-19 12:27:36 +05306742
6743int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6744 struct net_device *dev, u8 *peer)
6745{
6746 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6747 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6748
6749 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6750 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6751}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006752#endif
6753
Jeff Johnson295189b2012-06-20 16:38:30 -07006754/* cfg80211_ops */
6755static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6756{
6757 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6758 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6759 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6760 .change_station = wlan_hdd_change_station,
6761#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6762 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6763 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6764 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006765#else
6766 .start_ap = wlan_hdd_cfg80211_start_ap,
6767 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6768 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006769#endif
6770 .change_bss = wlan_hdd_cfg80211_change_bss,
6771 .add_key = wlan_hdd_cfg80211_add_key,
6772 .get_key = wlan_hdd_cfg80211_get_key,
6773 .del_key = wlan_hdd_cfg80211_del_key,
6774 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006775#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006777#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 .scan = wlan_hdd_cfg80211_scan,
6779 .connect = wlan_hdd_cfg80211_connect,
6780 .disconnect = wlan_hdd_cfg80211_disconnect,
6781 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6782 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6783 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6784 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6785 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6786#ifdef WLAN_FEATURE_P2P
6787 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6788 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6789 .mgmt_tx = wlan_hdd_action,
6790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6791 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6792 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6793 .set_txq_params = wlan_hdd_set_txq_params,
6794#endif
6795#endif
6796 .get_station = wlan_hdd_cfg80211_get_station,
6797 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6798 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006799 .add_station = wlan_hdd_cfg80211_add_station,
6800#ifdef FEATURE_WLAN_LFR
6801 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6802 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6803 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6804#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006805#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6806 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6807#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006808#ifdef FEATURE_WLAN_TDLS
6809 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6810 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6811#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006812};
6813
6814#endif // CONFIG_CFG80211