blob: bcd42f8ca9b94f6c75f028f7aaaf1d0d8e78a87d [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
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301364/*
1365 * FUNCTION: wlan_hdd_select_cbmode
1366 * called by wlan_hdd_cfg80211_start_bss() and
1367 * This function selects the cbmode based on primary channel
1368 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001369VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301370{
1371 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001372 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1373 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1374
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301375 if(
1376#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001377 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1378 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301379#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001380 SapHw_mode != eSAP_DOT11_MODE_11n &&
1381 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301382 )
1383 {
1384 return VOS_STATUS_SUCCESS;
1385 }
1386
1387 if (!pConfigIni->nChannelBondingMode5GHz) {
1388 return VOS_STATUS_SUCCESS;
1389 }
1390
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001391 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301392 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1393
1394 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1395
1396#ifdef WLAN_FEATURE_11AC
1397
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001398 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1399 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301400 {
1401 if ( channel== 36 || channel == 52 || channel == 100 ||
1402 channel == 116 || channel == 149 )
1403 {
1404 smeConfig.csrConfig.channelBondingMode5GHz =
1405 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1406 }
1407 else if ( channel == 40 || channel == 56 || channel == 104 ||
1408 channel == 120 || channel == 153 )
1409 {
1410 smeConfig.csrConfig.channelBondingMode5GHz =
1411 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1412 }
1413 else if ( channel == 44 || channel == 60 || channel == 108 ||
1414 channel == 124 || channel == 157 )
1415 {
1416 smeConfig.csrConfig.channelBondingMode5GHz =
1417 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1418 }
1419 else if ( channel == 48 || channel == 64 || channel == 112 ||
1420 channel == 128 || channel == 161 )
1421 {
1422 smeConfig.csrConfig.channelBondingMode5GHz =
1423 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1424 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301425 }
1426#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001427 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1428 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301429 {
1430 if ( channel== 40 || channel == 48 || channel == 56 ||
1431 channel == 64 || channel == 104 || channel == 112 ||
1432 channel == 120 || channel == 128 || channel == 136 ||
1433 channel == 144 || channel == 153 || channel == 161 )
1434 {
1435 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1436 }
1437 else if ( channel== 36 || channel == 44 || channel == 52 ||
1438 channel == 60 || channel == 100 || channel == 108 ||
1439 channel == 116 || channel == 124 || channel == 132 ||
1440 channel == 140 || channel == 149 || channel == 157 )
1441 {
1442 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1443 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301444 }
1445 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1446
1447 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1448 return VOS_STATUS_SUCCESS;
1449}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001450
Jeff Johnson295189b2012-06-20 16:38:30 -07001451#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1452static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1453 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001454#else
1455static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1456 struct cfg80211_beacon_data *params,
1457 const u8 *ssid, size_t ssid_len,
1458 enum nl80211_hidden_ssid hidden_ssid)
1459#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001460{
1461 tsap_Config_t *pConfig;
1462 beacon_data_t *pBeacon = NULL;
1463 struct ieee80211_mgmt *pMgmt_frame;
1464 v_U8_t *pIe=NULL;
1465 v_U16_t capab_info;
1466 eCsrAuthType RSNAuthType;
1467 eCsrEncryptionType RSNEncryptType;
1468 eCsrEncryptionType mcRSNEncryptType;
1469 int status = VOS_STATUS_SUCCESS;
1470 tpWLAN_SAPEventCB pSapEventCallback;
1471 hdd_hostapd_state_t *pHostapdState;
1472 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1473 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301474 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001475 struct qc_mac_acl_entry *acl_entry = NULL;
1476 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001477 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001478
1479 ENTER();
1480
1481 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1482
1483 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1484
1485 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1486
1487 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1488
1489 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1490
1491 //channel is already set in the set_channel Call back
1492 //pConfig->channel = pCommitConfig->channel;
1493
1494 /*Protection parameter to enable or disable*/
1495 pConfig->protEnabled =
1496 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1497
1498 pConfig->dtim_period = pBeacon->dtim_period;
1499
1500 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1501 pConfig->dtim_period);
1502
1503
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001504 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001505 {
1506 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001508 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001509 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001510 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001511 pConfig->ieee80211d = 1;
1512 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1513 sme_setRegInfo(hHal, pConfig->countryCode);
1514 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001516 else
1517 {
1518 pConfig->ieee80211d = 0;
1519 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301520 /*
1521 * If auto channel is configured i.e. channel is 0,
1522 * so skip channel validation.
1523 */
1524 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1525 {
1526 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1527 {
1528 hddLog(VOS_TRACE_LEVEL_ERROR,
1529 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1530 return -EINVAL;
1531 }
1532 }
1533 else
1534 {
1535 if(1 != pHddCtx->is_dynamic_channel_range_set)
1536 {
1537 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1538 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1539 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1540 }
1541 pHddCtx->is_dynamic_channel_range_set = 0;
1542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001544 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001545 {
1546 pConfig->ieee80211d = 0;
1547 }
1548 pConfig->authType = eSAP_AUTO_SWITCH;
1549
1550 capab_info = pMgmt_frame->u.beacon.capab_info;
1551
1552 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1553 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1554
1555 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1556
1557 /*Set wps station to configured*/
1558 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1559
1560 if(pIe)
1561 {
1562 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1563 {
1564 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1565 return -EINVAL;
1566 }
1567 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1568 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001569 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 /* Check 15 bit of WPS IE as it contain information for wps state
1571 * WPS state
1572 */
1573 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1574 {
1575 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1576 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1577 {
1578 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1579 }
1580 }
1581 }
1582 else
1583 {
1584 pConfig->wps_state = SAP_WPS_DISABLED;
1585 }
1586 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1587
1588 pConfig->RSNWPAReqIELength = 0;
1589 pConfig->pRSNWPAReqIE = NULL;
1590 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1591 WLAN_EID_RSN);
1592 if(pIe && pIe[1])
1593 {
1594 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1595 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1596 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1597 /* The actual processing may eventually be more extensive than
1598 * this. Right now, just consume any PMKIDs that are sent in
1599 * by the app.
1600 * */
1601 status = hdd_softap_unpackIE(
1602 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1603 &RSNEncryptType,
1604 &mcRSNEncryptType,
1605 &RSNAuthType,
1606 pConfig->pRSNWPAReqIE[1]+2,
1607 pConfig->pRSNWPAReqIE );
1608
1609 if( VOS_STATUS_SUCCESS == status )
1610 {
1611 /* Now copy over all the security attributes you have
1612 * parsed out
1613 * */
1614 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1615 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1616 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1617 = RSNEncryptType;
1618 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1619 "EncryptionType = %d mcEncryptionType = %d\n"),
1620 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1621 }
1622 }
1623
1624 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1625 pBeacon->tail, pBeacon->tail_len);
1626
1627 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1628 {
1629 if (pConfig->pRSNWPAReqIE)
1630 {
1631 /*Mixed mode WPA/WPA2*/
1632 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1633 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1634 }
1635 else
1636 {
1637 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1638 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1639 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1640 status = hdd_softap_unpackIE(
1641 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1642 &RSNEncryptType,
1643 &mcRSNEncryptType,
1644 &RSNAuthType,
1645 pConfig->pRSNWPAReqIE[1]+2,
1646 pConfig->pRSNWPAReqIE );
1647
1648 if( VOS_STATUS_SUCCESS == status )
1649 {
1650 /* Now copy over all the security attributes you have
1651 * parsed out
1652 * */
1653 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1654 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1655 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1656 = RSNEncryptType;
1657 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1658 "EncryptionType = %d mcEncryptionType = %d\n"),
1659 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1660 }
1661 }
1662 }
1663
1664 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1665
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001666#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 if (params->ssid != NULL)
1668 {
1669 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1670 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1671 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1672 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1673 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001674#else
1675 if (ssid != NULL)
1676 {
1677 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1678 pConfig->SSIDinfo.ssid.length = ssid_len;
1679 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1680 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1681 }
1682#endif
1683
Jeff Johnson295189b2012-06-20 16:38:30 -07001684 vos_mem_copy(pConfig->self_macaddr.bytes,
1685 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1686
1687 /* default value */
1688 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1689 pConfig->num_accept_mac = 0;
1690 pConfig->num_deny_mac = 0;
1691
1692 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1693 pBeacon->tail, pBeacon->tail_len);
1694
1695 /* pIe for black list is following form:
1696 type : 1 byte
1697 length : 1 byte
1698 OUI : 4 bytes
1699 acl type : 1 byte
1700 no of mac addr in black list: 1 byte
1701 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1702 */
1703 if ((pIe != NULL) && (pIe[1] != 0))
1704 {
1705 pConfig->SapMacaddr_acl = pIe[6];
1706 pConfig->num_deny_mac = pIe[7];
1707 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1708 pIe[6], pIe[7]);
1709 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1710 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1711 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1712 for (i = 0; i < pConfig->num_deny_mac; i++)
1713 {
1714 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1715 acl_entry++;
1716 }
1717 }
1718 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1719 pBeacon->tail, pBeacon->tail_len);
1720
1721 /* pIe for white list is following form:
1722 type : 1 byte
1723 length : 1 byte
1724 OUI : 4 bytes
1725 acl type : 1 byte
1726 no of mac addr in white list: 1 byte
1727 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1728 */
1729 if ((pIe != NULL) && (pIe[1] != 0))
1730 {
1731 pConfig->SapMacaddr_acl = pIe[6];
1732 pConfig->num_accept_mac = pIe[7];
1733 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1734 pIe[6], pIe[7]);
1735 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1736 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1737 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1738 for (i = 0; i < pConfig->num_accept_mac; i++)
1739 {
1740 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1741 acl_entry++;
1742 }
1743 }
1744 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1745
Jeff Johnsone7245742012-09-05 17:12:55 -07001746#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001747 /* Overwrite the hostapd setting for HW mode only for 11ac.
1748 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1749 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1750 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1751 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1752 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1753 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1754 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001755 {
1756 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1757 }
1758#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301759
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001760 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1761 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 // ht_capab is not what the name conveys,this is used for protection bitmap
1763 pConfig->ht_capab =
1764 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1765
1766 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1767 {
1768 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1769 return -EINVAL;
1770 }
1771
1772 //Uapsd Enabled Bit
1773 pConfig->UapsdEnable =
1774 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1775 //Enable OBSS protection
1776 pConfig->obssProtEnabled =
1777 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1778
1779 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1780 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1781 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1782 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1783 (int)pConfig->channel);
1784 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1785 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1786 pConfig->authType);
1787 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1788 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1789 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1790 pConfig->protEnabled, pConfig->obssProtEnabled);
1791
1792 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1793 {
1794 //Bss already started. just return.
1795 //TODO Probably it should update some beacon params.
1796 hddLog( LOGE, "Bss Already started...Ignore the request");
1797 EXIT();
1798 return 0;
1799 }
1800
1801 pConfig->persona = pHostapdAdapter->device_mode;
1802
1803 pSapEventCallback = hdd_hostapd_SAPEventCB;
1804 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1805 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1806 {
1807 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1808 return -EINVAL;
1809 }
1810
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001811 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001812 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1813
1814 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1815
1816 if (!VOS_IS_STATUS_SUCCESS(status))
1817 {
1818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 ("ERROR: HDD vos wait for single_event failed!!\n"));
1820 VOS_ASSERT(0);
1821 }
1822
1823 //Succesfully started Bss update the state bit.
1824 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1825
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001826#ifdef WLAN_FEATURE_P2P_DEBUG
1827 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1828 {
1829 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1830 {
1831 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1832 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001833 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001834 }
1835 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1836 {
1837 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1838 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001839 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001840 }
1841 }
1842#endif
1843
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 pHostapdState->bCommit = TRUE;
1845 EXIT();
1846
1847 return 0;
1848}
1849
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001850#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001851static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1852 struct net_device *dev,
1853 struct beacon_parameters *params)
1854{
1855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1856 int status=VOS_STATUS_SUCCESS;
1857
1858 ENTER();
1859
1860 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1861
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001862 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1863 {
1864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1865 "%s:LOGP in Progress. Ignore!!!", __func__);
1866 return -EAGAIN;
1867 }
1868
Jeff Johnson295189b2012-06-20 16:38:30 -07001869 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
1870#ifdef WLAN_FEATURE_P2P
1871 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1872#endif
1873 )
1874 {
1875 beacon_data_t *old,*new;
1876
1877 old = pAdapter->sessionCtx.ap.beacon;
1878
1879 if (old)
1880 return -EALREADY;
1881
1882 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1883
1884 if(status != VOS_STATUS_SUCCESS)
1885 {
1886 hddLog(VOS_TRACE_LEVEL_FATAL,
1887 "%s:Error!!! Allocating the new beacon\n",__func__);
1888 return -EINVAL;
1889 }
1890
1891 pAdapter->sessionCtx.ap.beacon = new;
1892
1893 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1894 }
1895
1896 EXIT();
1897 return status;
1898}
1899
1900static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
1901 struct net_device *dev,
1902 struct beacon_parameters *params)
1903{
1904 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1905 int status=VOS_STATUS_SUCCESS;
1906
1907 ENTER();
1908
1909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
1910 __func__,pAdapter->device_mode);
1911
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001912 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1913 {
1914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1915 "%s:LOGP in Progress. Ignore!!!", __func__);
1916 return -EAGAIN;
1917 }
1918
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1920#ifdef WLAN_FEATURE_P2P
1921 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1922#endif
1923 )
1924 {
1925 beacon_data_t *old,*new;
1926
1927 old = pAdapter->sessionCtx.ap.beacon;
1928
1929 if (!old)
1930 return -ENOENT;
1931
1932 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1933
1934 if(status != VOS_STATUS_SUCCESS) {
1935 hddLog(VOS_TRACE_LEVEL_FATAL,
1936 "%s: Error!!! Allocating the new beacon\n",__func__);
1937 return -EINVAL;
1938 }
1939
1940 pAdapter->sessionCtx.ap.beacon = new;
1941
1942 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1943 }
1944
1945 EXIT();
1946 return status;
1947}
1948
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001949#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1950
1951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001952static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
1953 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001954#else
1955static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
1956 struct net_device *dev)
1957#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001958{
1959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001960 hdd_context_t *pHddCtx = NULL;
1961 hdd_scaninfo_t *pScanInfo = NULL;
1962 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 VOS_STATUS status = 0;
1964
1965 ENTER();
1966
1967 if (NULL == pAdapter)
1968 {
1969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001970 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 return -ENODEV;
1972 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001973 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1974 {
1975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1976 "%s:LOGP in Progress. Ignore!!!", __func__);
1977 return -EAGAIN;
1978 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001979
1980 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1981 if (NULL == pHddCtx)
1982 {
1983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001984 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001985 return -ENODEV;
1986 }
1987
1988 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
1989 if (NULL == staAdapter)
1990 {
1991 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
1992 if (NULL == staAdapter)
1993 {
1994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001995 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001996 return -ENODEV;
1997 }
1998 }
1999
2000 pScanInfo = &pHddCtx->scan_info;
2001
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2003 {
2004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2005 return -EAGAIN;
2006 }
2007
2008 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2009
2010 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2011 __func__,pAdapter->device_mode);
2012
Jeff Johnsone7245742012-09-05 17:12:55 -07002013 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2014 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002015 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002016 hdd_abort_mac_scan(staAdapter->pHddCtx);
2017 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002018 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002019 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2020 if (!status)
2021 {
2022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002023 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002024 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002025 VOS_ASSERT(pScanInfo->mScanPending);
2026 return 0;
2027 }
2028 }
2029
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2031#ifdef WLAN_FEATURE_P2P
2032 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2033#endif
2034 )
2035 {
2036 beacon_data_t *old;
2037
2038 old = pAdapter->sessionCtx.ap.beacon;
2039
2040 if (!old)
2041 return -ENOENT;
2042
2043#ifdef CONFIG_CFG80211
2044 hdd_cleanup_actionframe(pHddCtx, pAdapter);
2045#endif
2046
2047 mutex_lock(&pHddCtx->sap_lock);
2048 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2049 {
2050 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2051 {
2052 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2053
2054 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2055
2056 if (!VOS_IS_STATUS_SUCCESS(status))
2057 {
2058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2059 ("ERROR: HDD vos wait for single_event failed!!\n"));
2060 VOS_ASSERT(0);
2061 }
2062 }
2063 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2064 }
2065 mutex_unlock(&pHddCtx->sap_lock);
2066
2067 if(status != VOS_STATUS_SUCCESS)
2068 {
2069 hddLog(VOS_TRACE_LEVEL_FATAL,
2070 "%s:Error!!! Stopping the BSS\n",__func__);
2071 return -EINVAL;
2072 }
2073
2074 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2075 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2076 ==eHAL_STATUS_FAILURE)
2077 {
2078 hddLog(LOGE,
2079 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2080 }
2081
2082 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2083 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2084 eANI_BOOLEAN_FALSE) )
2085 {
2086 hddLog(LOGE,
2087 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2088 }
2089
2090 // Reset WNI_CFG_PROBE_RSP Flags
2091 wlan_hdd_reset_prob_rspies(pAdapter);
2092
2093 pAdapter->sessionCtx.ap.beacon = NULL;
2094 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002095#ifdef WLAN_FEATURE_P2P_DEBUG
2096 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2097 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2098 {
2099 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2100 "GO got removed");
2101 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2102 }
2103#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 }
2105 EXIT();
2106 return status;
2107}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002108
2109#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2110
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302111static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2112 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002113 struct cfg80211_ap_settings *params)
2114{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302115 hdd_adapter_t *pAdapter;
2116 hdd_context_t *pHddCtx;
2117 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002118
2119 ENTER();
2120
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302121 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002122 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2124 "%s: Device is Null", __func__);
2125 return -ENODEV;
2126 }
2127
2128 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2129 if (NULL == pAdapter)
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2132 "%s: HDD adapter is Null", __func__);
2133 return -ENODEV;
2134 }
2135
2136 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2137 {
2138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2139 "%s: HDD adapter magic is invalid", __func__);
2140 return -ENODEV;
2141 }
2142
2143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2144 if (NULL == pHddCtx)
2145 {
2146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2147 "%s: HDD context is Null", __func__);
2148 return -ENODEV;
2149 }
2150
2151 if (pHddCtx->isLogpInProgress)
2152 {
2153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2154 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002155 return -EAGAIN;
2156 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302157
2158 if (pHddCtx->isLoadUnloadInProgress)
2159 {
2160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2161 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2162 return -EAGAIN;
2163 }
2164
2165 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2166 __func__, pAdapter->device_mode);
2167
2168 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002169#ifdef WLAN_FEATURE_P2P
2170 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2171#endif
2172 )
2173 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302174 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002175
2176 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302177
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002178 if (old)
2179 return -EALREADY;
2180
2181 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2182
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302183 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302186 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002187 return -EINVAL;
2188 }
2189 pAdapter->sessionCtx.ap.beacon = new;
2190 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2191 params->ssid_len, params->hidden_ssid);
2192 }
2193
2194 EXIT();
2195 return status;
2196}
2197
2198
2199static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2200 struct net_device *dev,
2201 struct cfg80211_beacon_data *params)
2202{
2203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2204 int status=VOS_STATUS_SUCCESS;
2205
2206 ENTER();
2207
2208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2209 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002210 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2211 {
2212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2213 return -EAGAIN;
2214 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002215
2216 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2217#ifdef WLAN_FEATURE_P2P
2218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2219#endif
2220 )
2221 {
2222 beacon_data_t *old,*new;
2223
2224 old = pAdapter->sessionCtx.ap.beacon;
2225
2226 if (!old)
2227 return -ENOENT;
2228
2229 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2230
2231 if(status != VOS_STATUS_SUCCESS) {
2232 hddLog(VOS_TRACE_LEVEL_FATAL,
2233 "%s: Error!!! Allocating the new beacon\n",__func__);
2234 return -EINVAL;
2235 }
2236
2237 pAdapter->sessionCtx.ap.beacon = new;
2238
2239 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2240 }
2241
2242 EXIT();
2243 return status;
2244}
2245
2246#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2247
Jeff Johnson295189b2012-06-20 16:38:30 -07002248
2249static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2250 struct net_device *dev,
2251 struct bss_parameters *params)
2252{
2253 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2254
2255 ENTER();
2256
2257 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2258 __func__,pAdapter->device_mode);
2259
2260 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2261#ifdef WLAN_FEATURE_P2P
2262 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2263#endif
2264 )
2265 {
2266 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2267 * want to update this parameter */
2268 if (-1 != params->ap_isolate)
2269 {
2270 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2271 }
2272 }
2273
2274 EXIT();
2275 return 0;
2276}
2277
2278/*
2279 * FUNCTION: wlan_hdd_cfg80211_change_iface
2280 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2281 */
2282int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2283 struct net_device *ndev,
2284 enum nl80211_iftype type,
2285 u32 *flags,
2286 struct vif_params *params
2287 )
2288{
2289 struct wireless_dev *wdev;
2290 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2291 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002292 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002293 tCsrRoamProfile *pRoamProfile = NULL;
2294 eCsrRoamBssType LastBSSType;
2295 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2296 eMib_dot11DesiredBssType connectedBssType;
2297 VOS_STATUS status;
2298
2299 ENTER();
2300
2301 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2302 {
2303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2304 return -EAGAIN;
2305 }
2306
2307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2308 __func__, pAdapter->device_mode);
2309
2310 wdev = ndev->ieee80211_ptr;
2311
2312#ifdef WLAN_BTAMP_FEATURE
2313 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2314 (NL80211_IFTYPE_ADHOC == type)||
2315 (NL80211_IFTYPE_AP == type)||
2316 (NL80211_IFTYPE_P2P_GO == type))
2317 {
2318 pHddCtx->isAmpAllowed = VOS_FALSE;
2319 // stop AMP traffic
2320 status = WLANBAP_StopAmp();
2321 if(VOS_STATUS_SUCCESS != status )
2322 {
2323 pHddCtx->isAmpAllowed = VOS_TRUE;
2324 hddLog(VOS_TRACE_LEVEL_FATAL,
2325 "%s: Failed to stop AMP", __func__);
2326 return -EINVAL;
2327 }
2328 }
2329#endif //WLAN_BTAMP_FEATURE
2330 /* Reset the current device mode bit mask*/
2331 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2332
2333 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2334#ifdef WLAN_FEATURE_P2P
2335 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002336 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002337#endif
2338 )
2339 {
2340 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2341 pRoamProfile = &pWextState->roamProfile;
2342 LastBSSType = pRoamProfile->BSSType;
2343
2344 switch (type)
2345 {
2346 case NL80211_IFTYPE_STATION:
2347#ifdef WLAN_FEATURE_P2P
2348 case NL80211_IFTYPE_P2P_CLIENT:
2349#endif
2350 hddLog(VOS_TRACE_LEVEL_INFO,
2351 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2352 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002353#ifdef WLAN_FEATURE_11AC
2354 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2355 {
2356 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2357 }
2358#endif
2359 pRoamProfile->phyMode =
2360 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 wdev->iftype = type;
2362#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002363 //Check for sub-string p2p to confirm its a p2p interface
2364 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002365 {
2366 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2367 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2368 }
2369 else
2370 {
2371 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002374#endif
2375 break;
2376 case NL80211_IFTYPE_ADHOC:
2377 hddLog(VOS_TRACE_LEVEL_INFO,
2378 "%s: setting interface Type to ADHOC", __func__);
2379 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2380 pRoamProfile->phyMode =
2381 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2382 wdev->iftype = type;
2383 break;
2384
2385 case NL80211_IFTYPE_AP:
2386#ifdef WLAN_FEATURE_P2P
2387 case NL80211_IFTYPE_P2P_GO:
2388#endif
2389 {
2390 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2391 "%s: setting interface Type to %s", __func__,
2392 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2393
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002394 //Cancel any remain on channel for GO mode
2395 if (NL80211_IFTYPE_P2P_GO == type)
2396 {
2397 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2398 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002399 if (NL80211_IFTYPE_AP == type)
2400 {
2401 /* As Loading WLAN Driver one interface being created for p2p device
2402 * address. This will take one HW STA and the max number of clients
2403 * that can connect to softAP will be reduced by one. so while changing
2404 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2405 * interface as it is not required in SoftAP mode.
2406 */
2407
2408 // Get P2P Adapter
2409 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2410
2411 if (pP2pAdapter)
2412 {
2413 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2414 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2415 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2416 }
2417 }
2418
Jeff Johnson295189b2012-06-20 16:38:30 -07002419 //De-init the adapter.
2420 hdd_stop_adapter( pHddCtx, pAdapter );
2421 hdd_deinit_adapter( pHddCtx, pAdapter );
2422 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2423#ifdef WLAN_SOFTAP_FEATURE
2424#ifdef WLAN_FEATURE_P2P
2425 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2426 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2427#else
2428 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2429#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002430
2431 //Disable BMPS and IMPS if enabled
2432 //before starting Go
2433 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2434 {
2435 if(VOS_STATUS_E_FAILURE ==
2436 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2437 {
2438 //Fail to Exit BMPS
2439 VOS_ASSERT(0);
2440 }
2441 }
2442
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002443 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2444 (pConfig->apRandomBssidEnabled))
2445 {
2446 /* To meet Android requirements create a randomized
2447 MAC address of the form 02:1A:11:Fx:xx:xx */
2448 get_random_bytes(&ndev->dev_addr[3], 3);
2449 ndev->dev_addr[0] = 0x02;
2450 ndev->dev_addr[1] = 0x1A;
2451 ndev->dev_addr[2] = 0x11;
2452 ndev->dev_addr[3] |= 0xF0;
2453 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2454 VOS_MAC_ADDR_SIZE);
2455 pr_info("wlan: Generated HotSpot BSSID "
2456 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2457 ndev->dev_addr[0],
2458 ndev->dev_addr[1],
2459 ndev->dev_addr[2],
2460 ndev->dev_addr[3],
2461 ndev->dev_addr[4],
2462 ndev->dev_addr[5]);
2463 }
2464
Jeff Johnson295189b2012-06-20 16:38:30 -07002465 hdd_set_ap_ops( pAdapter->dev );
2466
2467 status = hdd_init_ap_mode(pAdapter);
2468 if(status != VOS_STATUS_SUCCESS)
2469 {
2470 hddLog(VOS_TRACE_LEVEL_FATAL,
2471 "%s: Error initializing the ap mode", __func__);
2472 return -EINVAL;
2473 }
2474 hdd_set_conparam(1);
2475
2476#endif
2477 /*interface type changed update in wiphy structure*/
2478 if(wdev)
2479 {
2480 wdev->iftype = type;
2481 pHddCtx->change_iface = type;
2482 }
2483 else
2484 {
2485 hddLog(VOS_TRACE_LEVEL_ERROR,
2486 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2487 return -EINVAL;
2488 }
2489 goto done;
2490 }
2491
2492 default:
2493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2494 __func__);
2495 return -EOPNOTSUPP;
2496 }
2497 }
2498 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2499#ifdef WLAN_FEATURE_P2P
2500 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2501#endif
2502 )
2503 {
2504 switch(type)
2505 {
2506 case NL80211_IFTYPE_STATION:
2507#ifdef WLAN_FEATURE_P2P
2508 case NL80211_IFTYPE_P2P_CLIENT:
2509#endif
2510 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002511 hdd_stop_adapter( pHddCtx, pAdapter );
2512 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 wdev->iftype = type;
2514#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002515 //Check for sub-string p2p to confirm its a p2p interface
2516 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002517 {
2518 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2519 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2520 }
2521 else
2522 {
2523 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002524 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002526#endif
2527 hdd_set_conparam(0);
2528 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2530 hdd_set_station_ops( pAdapter->dev );
2531 status = hdd_init_station_mode( pAdapter );
2532 if( VOS_STATUS_SUCCESS != status )
2533 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002534 /* In case of JB, for P2P-GO, only change interface will be called,
2535 * This is the right place to enable back bmps_imps()
2536 */
2537 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002538 goto done;
2539 case NL80211_IFTYPE_AP:
2540#ifdef WLAN_FEATURE_P2P
2541 case NL80211_IFTYPE_P2P_GO:
2542#endif
2543 wdev->iftype = type;
2544#ifdef WLAN_FEATURE_P2P
2545 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2546 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2547#endif
2548 goto done;
2549 default:
2550 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2551 __func__);
2552 return -EOPNOTSUPP;
2553
2554 }
2555
2556 }
2557 else
2558 {
2559 return -EOPNOTSUPP;
2560 }
2561
2562
2563 if(pRoamProfile)
2564 {
2565 if ( LastBSSType != pRoamProfile->BSSType )
2566 {
2567 /*interface type changed update in wiphy structure*/
2568 wdev->iftype = type;
2569
2570 /*the BSS mode changed, We need to issue disconnect
2571 if connected or in IBSS disconnect state*/
2572 if ( hdd_connGetConnectedBssType(
2573 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2574 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2575 {
2576 /*need to issue a disconnect to CSR.*/
2577 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2578 if( eHAL_STATUS_SUCCESS ==
2579 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2580 pAdapter->sessionId,
2581 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2582 {
2583 wait_for_completion_interruptible_timeout(
2584 &pAdapter->disconnect_comp_var,
2585 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2586 }
2587 }
2588 }
2589 }
2590
2591done:
2592 /*set bitmask based on updated value*/
2593 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2594#ifdef WLAN_BTAMP_FEATURE
2595 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2596 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2597 {
2598 //we are ok to do AMP
2599 pHddCtx->isAmpAllowed = VOS_TRUE;
2600 }
2601#endif //WLAN_BTAMP_FEATURE
2602 EXIT();
2603 return 0;
2604}
2605
2606static int wlan_hdd_change_station(struct wiphy *wiphy,
2607 struct net_device *dev,
2608 u8 *mac,
2609 struct station_parameters *params)
2610{
2611 VOS_STATUS status = VOS_STATUS_SUCCESS;
2612 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2613 v_MACADDR_t STAMacAddress;
2614
Jeff Johnsone7245742012-09-05 17:12:55 -07002615 ENTER();
2616
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002617 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2618 {
2619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2620 "%s:LOGP in Progress. Ignore!!!", __func__);
2621 return -EAGAIN;
2622 }
2623
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2625
2626 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2627#ifdef WLAN_FEATURE_P2P
2628 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2629#endif
2630 )
2631 {
2632 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2633 {
2634 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2635 WLANTL_STA_AUTHENTICATED);
2636
2637 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002638 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002639 return -EINVAL;
2640 }
2641 }
2642
Jeff Johnsone7245742012-09-05 17:12:55 -07002643 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002644 return status;
2645}
2646
2647/*
2648 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2649 * This function is used to get peer station index in IBSS mode
2650 */
2651static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2652{
2653 u8 idx = 0;
2654 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2655 ENTER();
2656 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2657 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2658 {
2659 if ( (0 !=
2660 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2661 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2662 temp, VOS_MAC_ADDR_SIZE)
2663 )
2664 {
2665 return idx;
2666 }
2667 }
2668 return idx;
2669}
2670
2671
2672/*
2673 * FUNCTION: wlan_hdd_cfg80211_add_key
2674 * This function is used to initialize the key information
2675 */
2676#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2677static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2678 struct net_device *ndev,
2679 u8 key_index, bool pairwise,
2680 const u8 *mac_addr,
2681 struct key_params *params
2682 )
2683#else
2684static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2685 struct net_device *ndev,
2686 u8 key_index, const u8 *mac_addr,
2687 struct key_params *params
2688 )
2689#endif
2690{
2691 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2692 tCsrRoamSetKey setKey;
2693 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2694 int status = 0;
2695 v_U32_t roamId= 0xFF;
2696 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2697 hdd_hostapd_state_t *pHostapdState;
2698 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002699 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002700
2701 ENTER();
2702
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002703 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2704 {
2705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "%s:LOGP in Progress. Ignore!!!", __func__);
2707 return -EAGAIN;
2708 }
2709
Jeff Johnson295189b2012-06-20 16:38:30 -07002710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2711 __func__,pAdapter->device_mode);
2712
2713 if (CSR_MAX_NUM_KEY <= key_index)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2716 key_index);
2717
2718 return -EINVAL;
2719 }
2720
2721 hddLog(VOS_TRACE_LEVEL_INFO,
2722 "%s: called with key index = %d & key length %d",
2723 __func__, key_index, params->key_len);
2724
2725 /*extract key idx, key len and key*/
2726 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2727 setKey.keyId = key_index;
2728 setKey.keyLength = params->key_len;
2729 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2730
2731 switch (params->cipher)
2732 {
2733 case WLAN_CIPHER_SUITE_WEP40:
2734 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2735 break;
2736
2737 case WLAN_CIPHER_SUITE_WEP104:
2738 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2739 break;
2740
2741 case WLAN_CIPHER_SUITE_TKIP:
2742 {
2743 u8 *pKey = &setKey.Key[0];
2744 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2745
2746 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2747
2748 /*Supplicant sends the 32bytes key in this order
2749
2750 |--------------|----------|----------|
2751 | Tk1 |TX-MIC | RX Mic |
2752 |--------------|----------|----------|
2753 <---16bytes---><--8bytes--><--8bytes-->
2754
2755 */
2756 /*Sme expects the 32 bytes key to be in the below order
2757
2758 |--------------|----------|----------|
2759 | Tk1 |RX-MIC | TX Mic |
2760 |--------------|----------|----------|
2761 <---16bytes---><--8bytes--><--8bytes-->
2762 */
2763 /* Copy the Temporal Key 1 (TK1) */
2764 vos_mem_copy(pKey, params->key,16);
2765
2766 /*Copy the rx mic first*/
2767 vos_mem_copy(&pKey[16],&params->key[24],8);
2768
2769 /*Copy the tx mic */
2770 vos_mem_copy(&pKey[24],&params->key[16],8);
2771
2772
2773 break;
2774 }
2775
2776 case WLAN_CIPHER_SUITE_CCMP:
2777 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2778 break;
2779
2780#ifdef FEATURE_WLAN_WAPI
2781 case WLAN_CIPHER_SUITE_SMS4:
2782 {
2783 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2784 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2785 params->key, params->key_len);
2786 return 0;
2787 }
2788#endif
2789#ifdef FEATURE_WLAN_CCX
2790 case WLAN_CIPHER_SUITE_KRK:
2791 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2792 break;
2793#endif
2794 default:
2795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2796 __func__, params->cipher);
2797 return -EOPNOTSUPP;
2798 }
2799
2800 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2801 __func__, setKey.encType);
2802
2803
2804
2805 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2806#ifdef WLAN_FEATURE_P2P
2807 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2808#endif
2809 )
2810 {
2811
2812
2813 if (
2814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2815 (!pairwise)
2816#else
2817 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2818#endif
2819 )
2820 {
2821 /* set group key*/
2822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08002823 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002824 __func__, __LINE__);
2825 setKey.keyDirection = eSIR_RX_ONLY;
2826 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2827 }
2828 else
2829 {
2830 /* set pairwise key*/
2831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2832 "%s- %d: setting pairwise key",
2833 __func__, __LINE__);
2834 setKey.keyDirection = eSIR_TX_RX;
2835 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2836 }
2837
2838 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2839 if( pHostapdState->bssState == BSS_START )
2840 {
2841 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2842
2843 if ( status != eHAL_STATUS_SUCCESS )
2844 {
2845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2846 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2847 __LINE__, status );
2848 }
2849 }
2850
2851 /* Saving WEP keys */
2852 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2853 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2854 {
2855 //Save the wep key in ap context. Issue setkey after the BSS is started.
2856 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2857 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2858 }
2859 else
2860 {
2861 //Save the key in ap context. Issue setkey after the BSS is started.
2862 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2863 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
2864 }
2865 }
2866 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2867#ifdef WLAN_FEATURE_P2P
2868 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2869#endif
2870 )
2871 {
2872 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2873 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2874
2875 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
2876
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08002877 pWextState->roamProfile.Keys.defaultIndex = key_index;
2878
2879
Jeff Johnson295189b2012-06-20 16:38:30 -07002880 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
2881 params->key, params->key_len);
2882
2883 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
2884
2885 if (!( ( IW_AUTH_KEY_MGMT_802_1X
2886 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2887 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
2888 )
2889 &&
2890 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
2891 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
2892 )
2893 )
2894 {
2895 /* in case of static WEP, macaddr/bssid is not coming from nl80211
2896 * interface, copy bssid for pairwise key and group macaddr for
2897 * group key initialization*/
2898
2899 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2900
2901 pWextState->roamProfile.negotiatedUCEncryptionType =
2902 pHddStaCtx->conn_info.ucEncryptionType =
2903 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
2904 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
2905 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
2906
2907
2908 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2909 "%s: Negotiated encryption type %d", __func__,
2910 pWextState->roamProfile.negotiatedUCEncryptionType);
2911
2912 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
2913 &pWextState->roamProfile, true);
2914 setKey.keyLength = 0;
2915 setKey.keyDirection = eSIR_TX_RX;
2916
2917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2918 if (pairwise)
2919 {
2920#endif
2921 if (mac_addr)
2922 {
2923 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2924 }
2925 else
2926 {
2927 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
2928 * and peerMacAddress in case of IBSS*/
2929 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
2930 {
2931 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
2932 if (HDD_MAX_NUM_IBSS_STA != staidx)
2933 {
2934 vos_mem_copy(setKey.peerMac,
2935 &pHddStaCtx->conn_info.peerMacAddress[staidx],
2936 WNI_CFG_BSSID_LEN);
2937
2938 }
2939 else
2940 {
2941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
2942 __func__);
2943 return -EOPNOTSUPP;
2944 }
2945 }
2946 else
2947 {
2948 vos_mem_copy(setKey.peerMac,
2949 &pHddStaCtx->conn_info.bssId[0],
2950 WNI_CFG_BSSID_LEN);
2951 }
2952 }
2953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2954 }
2955 else
2956 {
2957 /* set group key*/
2958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2959 "%s- %d: setting Group key",
2960 __func__, __LINE__);
2961 setKey.keyDirection = eSIR_RX_ONLY;
2962 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
2963 }
2964#endif
2965 }
2966 else if (
2967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2968 (!pairwise)
2969#else
2970 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2971#endif
2972 )
2973 {
2974 /* set group key*/
2975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2976 "%s- %d: setting Group key",
2977 __func__, __LINE__);
2978 setKey.keyDirection = eSIR_RX_ONLY;
2979 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2980 }
2981 else
2982 {
2983 /* set pairwise key*/
2984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2985 "%s- %d: setting pairwise key",
2986 __func__, __LINE__);
2987 setKey.keyDirection = eSIR_TX_RX;
2988 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2989 }
2990
2991 hddLog(VOS_TRACE_LEVEL_INFO_MED,
2992 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
2993 __func__, setKey.peerMac[0], setKey.peerMac[1],
2994 setKey.peerMac[2], setKey.peerMac[3],
2995 setKey.peerMac[4], setKey.peerMac[5],
2996 setKey.keyDirection);
2997
2998 vos_status = wlan_hdd_check_ula_done(pAdapter);
2999
3000 if ( vos_status != VOS_STATUS_SUCCESS )
3001 {
3002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3003 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3004 __LINE__, vos_status );
3005
3006 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3007
3008 return -EINVAL;
3009
3010 }
3011
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003012#ifdef WLAN_FEATURE_VOWIFI_11R
3013 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3014 Save the key in the UMAC and include it in the ADD BSS request */
3015 /*TODO 11r - is this used?? */
3016 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
3017 if( halStatus == eHAL_STATUS_SUCCESS )
3018 {
3019 return halStatus;
3020 }
3021#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003022
3023 /* issue set key request to SME*/
3024 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3025 pAdapter->sessionId, &setKey, &roamId );
3026
3027 if ( 0 != status )
3028 {
3029 hddLog(VOS_TRACE_LEVEL_ERROR,
3030 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3031 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3032 return -EINVAL;
3033 }
3034
3035
3036 /* in case of IBSS as there was no information available about WEP keys during
3037 * IBSS join, group key intialized with NULL key, so re-initialize group key
3038 * with correct value*/
3039 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3040 !( ( IW_AUTH_KEY_MGMT_802_1X
3041 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3042 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3043 )
3044 &&
3045 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3046 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3047 )
3048 )
3049 {
3050 setKey.keyDirection = eSIR_RX_ONLY;
3051 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3052
3053 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3054 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3055 __func__, setKey.peerMac[0], setKey.peerMac[1],
3056 setKey.peerMac[2], setKey.peerMac[3],
3057 setKey.peerMac[4], setKey.peerMac[5],
3058 setKey.keyDirection);
3059
3060 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3061 pAdapter->sessionId, &setKey, &roamId );
3062
3063 if ( 0 != status )
3064 {
3065 hddLog(VOS_TRACE_LEVEL_ERROR,
3066 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3067 __func__, status);
3068 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3069 return -EINVAL;
3070 }
3071 }
3072 }
3073
3074 return 0;
3075}
3076
3077/*
3078 * FUNCTION: wlan_hdd_cfg80211_get_key
3079 * This function is used to get the key information
3080 */
3081#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3082static int wlan_hdd_cfg80211_get_key(
3083 struct wiphy *wiphy,
3084 struct net_device *ndev,
3085 u8 key_index, bool pairwise,
3086 const u8 *mac_addr, void *cookie,
3087 void (*callback)(void *cookie, struct key_params*)
3088 )
3089#else
3090static int wlan_hdd_cfg80211_get_key(
3091 struct wiphy *wiphy,
3092 struct net_device *ndev,
3093 u8 key_index, const u8 *mac_addr, void *cookie,
3094 void (*callback)(void *cookie, struct key_params*)
3095 )
3096#endif
3097{
3098 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3099 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3100 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3101 struct key_params params;
3102
3103 ENTER();
3104
3105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3106 __func__,pAdapter->device_mode);
3107
3108 memset(&params, 0, sizeof(params));
3109
3110 if (CSR_MAX_NUM_KEY <= key_index)
3111 {
3112 return -EINVAL;
3113 }
3114
3115 switch(pRoamProfile->EncryptionType.encryptionType[0])
3116 {
3117 case eCSR_ENCRYPT_TYPE_NONE:
3118 params.cipher = IW_AUTH_CIPHER_NONE;
3119 break;
3120
3121 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3122 case eCSR_ENCRYPT_TYPE_WEP40:
3123 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3124 break;
3125
3126 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3127 case eCSR_ENCRYPT_TYPE_WEP104:
3128 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3129 break;
3130
3131 case eCSR_ENCRYPT_TYPE_TKIP:
3132 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3133 break;
3134
3135 case eCSR_ENCRYPT_TYPE_AES:
3136 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3137 break;
3138
3139 default:
3140 params.cipher = IW_AUTH_CIPHER_NONE;
3141 break;
3142 }
3143
3144 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3145 params.seq_len = 0;
3146 params.seq = NULL;
3147 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3148 callback(cookie, &params);
3149 return 0;
3150}
3151
3152/*
3153 * FUNCTION: wlan_hdd_cfg80211_del_key
3154 * This function is used to delete the key information
3155 */
3156#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3157static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3158 struct net_device *ndev,
3159 u8 key_index,
3160 bool pairwise,
3161 const u8 *mac_addr
3162 )
3163#else
3164static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3165 struct net_device *ndev,
3166 u8 key_index,
3167 const u8 *mac_addr
3168 )
3169#endif
3170{
3171 int status = 0;
3172
3173 //This code needs to be revisited. There is sme_removeKey API, we should
3174 //plan to use that. After the change to use correct index in setkey,
3175 //it is observed that this is invalidating peer
3176 //key index whenever re-key is done. This is affecting data link.
3177 //It should be ok to ignore del_key.
3178#if 0
3179 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3180 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3181 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3182 tCsrRoamSetKey setKey;
3183 v_U32_t roamId= 0xFF;
3184
3185 ENTER();
3186
3187 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3188 __func__,pAdapter->device_mode);
3189
3190 if (CSR_MAX_NUM_KEY <= key_index)
3191 {
3192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3193 key_index);
3194
3195 return -EINVAL;
3196 }
3197
3198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3199 setKey.keyId = key_index;
3200
3201 if (mac_addr)
3202 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3203 else
3204 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3205
3206 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3207
3208 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3209#ifdef WLAN_FEATURE_P2P
3210 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3211#endif
3212 )
3213 {
3214
3215 hdd_hostapd_state_t *pHostapdState =
3216 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3217 if( pHostapdState->bssState == BSS_START)
3218 {
3219 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3220
3221 if ( status != eHAL_STATUS_SUCCESS )
3222 {
3223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3224 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3225 __LINE__, status );
3226 }
3227 }
3228 }
3229 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3230#ifdef WLAN_FEATURE_P2P
3231 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3232#endif
3233 )
3234 {
3235 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3236
3237 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3238
3239 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3240 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3241 __func__, setKey.peerMac[0], setKey.peerMac[1],
3242 setKey.peerMac[2], setKey.peerMac[3],
3243 setKey.peerMac[4], setKey.peerMac[5]);
3244 if(pAdapter->sessionCtx.station.conn_info.connState ==
3245 eConnectionState_Associated)
3246 {
3247 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3248 pAdapter->sessionId, &setKey, &roamId );
3249
3250 if ( 0 != status )
3251 {
3252 hddLog(VOS_TRACE_LEVEL_ERROR,
3253 "%s: sme_RoamSetKey failure, returned %d",
3254 __func__, status);
3255 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3256 return -EINVAL;
3257 }
3258 }
3259 }
3260#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003261 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003262 return status;
3263}
3264
3265/*
3266 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3267 * This function is used to set the default tx key index
3268 */
3269#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3270static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3271 struct net_device *ndev,
3272 u8 key_index,
3273 bool unicast, bool multicast)
3274#else
3275static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3276 struct net_device *ndev,
3277 u8 key_index)
3278#endif
3279{
3280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3281 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3282 int status = 0;
3283 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3284
3285 ENTER();
3286
3287 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3288 __func__,pAdapter->device_mode, key_index);
3289
3290 if (CSR_MAX_NUM_KEY <= key_index)
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3293 key_index);
3294
3295 return -EINVAL;
3296 }
3297
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003298 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3299 {
3300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3301 "%s:LOGP in Progress. Ignore!!!", __func__);
3302 return -EAGAIN;
3303 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003304
3305 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3306#ifdef WLAN_FEATURE_P2P
3307 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3308#endif
3309 )
3310 {
3311 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3312 (eCSR_ENCRYPT_TYPE_TKIP !=
3313 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3314 (eCSR_ENCRYPT_TYPE_AES !=
3315 pWextState->roamProfile.EncryptionType.encryptionType[0])
3316 )
3317 {
3318 /* if default key index is not same as previous one,
3319 * then update the default key index */
3320
3321 tCsrRoamSetKey setKey;
3322 v_U32_t roamId= 0xFF;
3323 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3324
3325 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3326 __func__, key_index);
3327
3328 Keys->defaultIndex = (u8)key_index;
3329 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3330 setKey.keyId = key_index;
3331 setKey.keyLength = Keys->KeyLength[key_index];
3332
3333 vos_mem_copy(&setKey.Key[0],
3334 &Keys->KeyMaterial[key_index][0],
3335 Keys->KeyLength[key_index]);
3336
3337 setKey.keyDirection = eSIR_TX_ONLY;
3338
3339 vos_mem_copy(setKey.peerMac,
3340 &pHddStaCtx->conn_info.bssId[0],
3341 WNI_CFG_BSSID_LEN);
3342
3343 setKey.encType =
3344 pWextState->roamProfile.EncryptionType.encryptionType[0];
3345
3346 /* issue set key request */
3347 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3348 pAdapter->sessionId, &setKey, &roamId );
3349
3350 if ( 0 != status )
3351 {
3352 hddLog(VOS_TRACE_LEVEL_ERROR,
3353 "%s: sme_RoamSetKey failed, returned %d", __func__,
3354 status);
3355 return -EINVAL;
3356 }
3357 }
3358 }
3359
3360 /* In SoftAp mode setting key direction for default mode */
3361 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3362 {
3363 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3364 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3365 (eCSR_ENCRYPT_TYPE_AES !=
3366 pWextState->roamProfile.EncryptionType.encryptionType[0])
3367 )
3368 {
3369 /* Saving key direction for default key index to TX default */
3370 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3371 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3372 }
3373 }
3374
3375 return status;
3376}
3377
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08003378#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07003379/**
3380 * FUNCTION: wlan_hdd_cfg80211_set_channel
3381 * This function is used to set the channel number
3382 */
3383int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
3384 struct ieee80211_channel *chan,
3385 enum nl80211_channel_type channel_type
3386 )
3387{
3388 v_U32_t num_ch = 0;
3389 u32 channel = 0;
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003390 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003391 int freq = chan->center_freq; /* freq is in MHZ */
3392
3393 ENTER();
Madan Mohan Koyyalamudi73305412012-11-30 17:21:40 -08003394
3395 if( NULL == dev )
3396 {
3397 hddLog(VOS_TRACE_LEVEL_ERROR,
3398 "%s: Called with dev = NULL.\n", __func__);
3399 return -ENODEV;
3400 }
3401 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003402
3403 hddLog(VOS_TRACE_LEVEL_INFO,
3404 "%s: device_mode = %d freq = %d \n",__func__,
3405 pAdapter->device_mode, chan->center_freq);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07003406 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3407 {
3408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3409 return -EAGAIN;
3410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003411
3412 /*
3413 * Do freq to chan conversion
3414 * TODO: for 11a
3415 */
3416
3417 channel = ieee80211_frequency_to_channel(freq);
3418
3419 /* Check freq range */
3420 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3421 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
3422 {
3423 hddLog(VOS_TRACE_LEVEL_ERROR,
3424 "%s: Channel [%d] is outside valid range from %d to %d\n",
3425 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3426 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3427 return -EINVAL;
3428 }
3429
3430 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3431
3432 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
3433#ifdef WLAN_FEATURE_P2P
3434 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
3435#endif
3436 )
3437 {
3438 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
3439 {
3440 hddLog(VOS_TRACE_LEVEL_ERROR,
3441 "%s: Invalid Channel [%d] \n", __func__, channel);
3442 return -EINVAL;
3443 }
3444 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3445 "%s: set channel to [%d] for device mode =%d",
3446 __func__, channel,pAdapter->device_mode);
3447 }
3448 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3449#ifdef WLAN_FEATURE_P2P
3450 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3451#endif
3452 )
3453 {
3454 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3455 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
3456 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3457
3458 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
3459 {
3460 /* Link is up then return cant set channel*/
3461 hddLog( VOS_TRACE_LEVEL_ERROR,
3462 "%s: IBSS Associated, can't set the channel\n", __func__);
3463 return -EINVAL;
3464 }
3465
3466 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
3467 pHddStaCtx->conn_info.operationChannel = channel;
3468 pRoamProfile->ChannelInfo.ChannelList =
3469 &pHddStaCtx->conn_info.operationChannel;
3470 }
3471 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3472#ifdef WLAN_FEATURE_P2P
3473 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3474#endif
3475 )
3476 {
3477 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
3478
3479 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3480 {
3481 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3482
3483 /* If auto channel selection is configured as enable/ 1 then ignore
3484 channel set by supplicant
3485 */
3486 if ( cfg_param->apAutoChannelSelection )
3487 {
3488 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
3489
3490 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3491 "%s: set channel to auto channel (0) for device mode =%d",
3492 __func__, pAdapter->device_mode);
3493 }
3494 }
3495 }
3496 else
3497 {
3498 hddLog(VOS_TRACE_LEVEL_FATAL,
3499 "%s: Invalid device mode failed to set valid channel", __func__);
3500 return -EINVAL;
3501 }
3502 EXIT();
3503 return 0;
3504}
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08003505#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003506
3507
3508
3509/*
3510 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3511 * This function is used to inform the BSS details to nl80211 interface.
3512 */
3513static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3514 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3515{
3516 struct net_device *dev = pAdapter->dev;
3517 struct wireless_dev *wdev = dev->ieee80211_ptr;
3518 struct wiphy *wiphy = wdev->wiphy;
3519 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3520 int chan_no;
3521 int ie_length;
3522 const char *ie;
3523 unsigned int freq;
3524 struct ieee80211_channel *chan;
3525 int rssi = 0;
3526 struct cfg80211_bss *bss = NULL;
3527
3528 ENTER();
3529
3530 if( NULL == pBssDesc )
3531 {
3532 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3533 return bss;
3534 }
3535
3536 chan_no = pBssDesc->channelId;
3537 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3538 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3539
3540 if( NULL == ie )
3541 {
3542 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3543 return bss;
3544 }
3545
3546#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3547 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3548 {
3549 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3550 }
3551 else
3552 {
3553 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3554 }
3555#else
3556 freq = ieee80211_channel_to_frequency(chan_no);
3557#endif
3558
3559 chan = __ieee80211_get_channel(wiphy, freq);
3560
3561 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3562 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3563 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3564 if (bss == NULL)
3565 {
3566 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3567
3568 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3569 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3570 pBssDesc->capabilityInfo,
3571 pBssDesc->beaconInterval, ie, ie_length,
3572 rssi, GFP_KERNEL ));
3573}
3574 else
3575 {
3576 return bss;
3577 }
3578}
3579
3580
3581
3582/*
3583 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3584 * This function is used to inform the BSS details to nl80211 interface.
3585 */
3586struct cfg80211_bss*
3587wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3588 tSirBssDescription *bss_desc
3589 )
3590{
3591 /*
3592 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3593 already exists in bss data base of cfg80211 for that particular BSS ID.
3594 Using cfg80211_inform_bss_frame to update the bss entry instead of
3595 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3596 now there is no possibility to get the mgmt(probe response) frame from PE,
3597 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3598 cfg80211_inform_bss_frame.
3599 */
3600 struct net_device *dev = pAdapter->dev;
3601 struct wireless_dev *wdev = dev->ieee80211_ptr;
3602 struct wiphy *wiphy = wdev->wiphy;
3603 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003604#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3605 qcom_ie_age *qie_age = NULL;
3606 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3607#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003608 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003609#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 const char *ie =
3611 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3612 unsigned int freq;
3613 struct ieee80211_channel *chan;
3614 struct ieee80211_mgmt *mgmt =
3615 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3616 struct cfg80211_bss *bss_status = NULL;
3617 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3618 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003619#ifdef WLAN_OPEN_SOURCE
3620 struct timespec ts;
3621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003622
3623 ENTER();
3624
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003625 if (!mgmt)
3626 return NULL;
3627
Jeff Johnson295189b2012-06-20 16:38:30 -07003628 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003629
3630#ifdef WLAN_OPEN_SOURCE
3631 /* Android does not want the timestamp from the frame.
3632 Instead it wants a monotonic increasing value */
3633 get_monotonic_boottime(&ts);
3634 mgmt->u.probe_resp.timestamp =
3635 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3636#else
3637 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003638 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3639 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003640
3641#endif
3642
Jeff Johnson295189b2012-06-20 16:38:30 -07003643 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3644 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003645
3646#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3647 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3648 /* Assuming this is the last IE, copy at the end */
3649 ie_length -=sizeof(qcom_ie_age);
3650 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3651 qie_age->element_id = QCOM_VENDOR_IE_ID;
3652 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3653 qie_age->oui_1 = QCOM_OUI1;
3654 qie_age->oui_2 = QCOM_OUI2;
3655 qie_age->oui_3 = QCOM_OUI3;
3656 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3657 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3658#endif
3659
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3661
3662 mgmt->frame_control |=
3663 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3664
3665#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3666 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3667 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3668 {
3669 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3670 }
3671 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3672 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3673
3674 {
3675 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3676 }
3677 else
3678 {
3679 kfree(mgmt);
3680 return NULL;
3681 }
3682#else
3683 freq = ieee80211_channel_to_frequency(chan_no);
3684#endif
3685 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003686 /*when the band is changed on the fly using the GUI, three things are done
3687 * 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)
3688 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3689 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3690 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3691 * and discards the channels correponding to previous band and calls back with zero bss results.
3692 * 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
3693 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3694 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3695 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3696 * So drop the bss and continue to next bss.
3697 */
3698 if(chan == NULL)
3699 {
3700 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3701 return NULL;
3702 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003703 /*To keep the rssi icon of the connected AP in the scan window
3704 *and the rssi icon of the wireless networks in sync
3705 * */
3706 if (( eConnectionState_Associated ==
3707 pAdapter->sessionCtx.station.conn_info.connState ) &&
3708 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3709 pAdapter->sessionCtx.station.conn_info.bssId,
3710 WNI_CFG_BSSID_LEN)))
3711 {
3712 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3713 rssi = (pAdapter->rssi * 100);
3714 }
3715 else
3716 {
3717 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3718 }
3719
3720 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3721 frame_len, rssi, GFP_KERNEL);
3722 kfree(mgmt);
3723 return bss_status;
3724}
3725
3726/*
3727 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3728 * This function is used to update the BSS data base of CFG8011
3729 */
3730struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3731 tCsrRoamInfo *pRoamInfo
3732 )
3733{
3734 tCsrRoamConnectedProfile roamProfile;
3735 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3736 struct cfg80211_bss *bss = NULL;
3737
3738 ENTER();
3739
3740 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3741 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3742
3743 if (NULL != roamProfile.pBssDesc)
3744 {
3745 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3746 &roamProfile);
3747
3748 if (NULL == bss)
3749 {
3750 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3751 __func__);
3752 }
3753
3754 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3755 }
3756 else
3757 {
3758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3759 __func__);
3760 }
3761 return bss;
3762}
3763
3764/*
3765 * FUNCTION: wlan_hdd_cfg80211_update_bss
3766 */
3767static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3768 hdd_adapter_t *pAdapter
3769 )
3770{
3771 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3772 tCsrScanResultInfo *pScanResult;
3773 eHalStatus status = 0;
3774 tScanResultHandle pResult;
3775 struct cfg80211_bss *bss_status = NULL;
3776
3777 ENTER();
3778
3779 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3780 {
3781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3782 return -EAGAIN;
3783 }
3784
3785 /*
3786 * start getting scan results and populate cgf80211 BSS database
3787 */
3788 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3789
3790 /* no scan results */
3791 if (NULL == pResult)
3792 {
3793 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3794 return status;
3795 }
3796
3797 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3798
3799 while (pScanResult)
3800 {
3801 /*
3802 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3803 * entry already exists in bss data base of cfg80211 for that
3804 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3805 * bss entry instead of cfg80211_inform_bss, But this call expects
3806 * mgmt packet as input. As of now there is no possibility to get
3807 * the mgmt(probe response) frame from PE, converting bss_desc to
3808 * ieee80211_mgmt(probe response) and passing to c
3809 * fg80211_inform_bss_frame.
3810 * */
3811
3812 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3813 &pScanResult->BssDescriptor);
3814
3815
3816 if (NULL == bss_status)
3817 {
3818 hddLog(VOS_TRACE_LEVEL_INFO,
3819 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3820 }
3821 else
3822 {
3823 cfg80211_put_bss(bss_status);
3824 }
3825
3826 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3827 }
3828
3829 sme_ScanResultPurge(hHal, pResult);
3830
3831 return 0;
3832}
3833
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003834void
3835hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3836{
3837 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003838 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3839 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3840 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003841} /****** end hddPrintMacAddr() ******/
3842
3843void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003844hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003845{
3846 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003847 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3848 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3849 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3850 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003851} /****** end hddPrintPmkId() ******/
3852
3853//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3854//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3855
3856//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3857//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3858
3859#define dump_bssid(bssid) \
3860 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003861 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3862 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3863 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003864 }
3865
3866#define dump_pmkid(pMac, pmkid) \
3867 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003868 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3869 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3870 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003871 }
3872
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003873#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003874/*
3875 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3876 * This function is used to notify the supplicant of a new PMKSA candidate.
3877 */
3878int wlan_hdd_cfg80211_pmksa_candidate_notify(
3879 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3880 int index, bool preauth )
3881{
Jeff Johnsone7245742012-09-05 17:12:55 -07003882#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003883 struct net_device *dev = pAdapter->dev;
3884
3885 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003886 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003887
3888 if( NULL == pRoamInfo )
3889 {
3890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3891 return -EINVAL;
3892 }
3893
3894 dump_bssid(pRoamInfo->bssid);
3895 cfg80211_pmksa_candidate_notify(dev, index,
3896 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003897#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003898 return 0;
3899}
3900#endif //FEATURE_WLAN_LFR
3901
Jeff Johnson295189b2012-06-20 16:38:30 -07003902/*
3903 * FUNCTION: hdd_cfg80211_scan_done_callback
3904 * scanning callback function, called after finishing scan
3905 *
3906 */
3907static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3908 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3909{
3910 struct net_device *dev = (struct net_device *) pContext;
3911 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003913 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3914 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003915 struct cfg80211_scan_request *req = NULL;
3916 int ret = 0;
3917
3918 ENTER();
3919
3920 hddLog(VOS_TRACE_LEVEL_INFO,
3921 "%s called with halHandle = %p, pContext = %p,"
3922 "scanID = %d, returned status = %d\n",
3923 __func__, halHandle, pContext, (int) scanId, (int) status);
3924
3925 //Block on scan req completion variable. Can't wait forever though.
3926 ret = wait_for_completion_interruptible_timeout(
3927 &pScanInfo->scan_req_completion_event,
3928 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3929 if (!ret)
3930 {
3931 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003932 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 }
3934
3935 if(pScanInfo->mScanPending != VOS_TRUE)
3936 {
3937 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003938 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003939 }
3940
3941 /* Check the scanId */
3942 if (pScanInfo->scanId != scanId)
3943 {
3944 hddLog(VOS_TRACE_LEVEL_INFO,
3945 "%s called with mismatched scanId pScanInfo->scanId = %d "
3946 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3947 (int) scanId);
3948 }
3949
Jeff Johnson295189b2012-06-20 16:38:30 -07003950 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3951 pAdapter);
3952
3953 if (0 > ret)
3954 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3955
3956
3957 /* If any client wait scan result through WEXT
3958 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003959 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 {
3961 /* The other scan request waiting for current scan finish
3962 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003963 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003964 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003965 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 }
3967 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003968 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003969 {
3970 struct net_device *dev = pAdapter->dev;
3971 union iwreq_data wrqu;
3972 int we_event;
3973 char *msg;
3974
3975 memset(&wrqu, '\0', sizeof(wrqu));
3976 we_event = SIOCGIWSCAN;
3977 msg = NULL;
3978 wireless_send_event(dev, we_event, &wrqu, msg);
3979 }
3980 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003981 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003982
3983 /* Get the Scan Req */
3984 req = pAdapter->request;
3985
3986 if (!req)
3987 {
3988 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003989 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003990 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 }
3992
3993 /*
3994 * setting up 0, just in case.
3995 */
3996 req->n_ssids = 0;
3997 req->n_channels = 0;
3998 req->ie = 0;
3999
Jeff Johnson295189b2012-06-20 16:38:30 -07004000 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004001 /* Scan is no longer pending */
4002 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004003
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004004 /*
4005 * cfg80211_scan_done informing NL80211 about completion
4006 * of scanning
4007 */
4008 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004009 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004010
Jeff Johnsone7245742012-09-05 17:12:55 -07004011allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004012 /* release the wake lock at the end of the scan*/
4013 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004014
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004015 /* Acquire wakelock to handle the case where APP's tries to suspend
4016 * immediatly after the driver gets connect request(i.e after scan)
4017 * from supplicant, this result in app's is suspending and not able
4018 * to process the connect request to AP */
4019 hdd_allow_suspend_timeout(100);
4020
Jeff Johnson295189b2012-06-20 16:38:30 -07004021 EXIT();
4022 return 0;
4023}
4024
4025/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004026 * FUNCTION: hdd_isScanAllowed
4027 * Go through each adapter and check if scan allowed
4028 *
4029 */
4030v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4031{
4032 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4033 hdd_station_ctx_t *pHddStaCtx = NULL;
4034 hdd_adapter_t *pAdapter = NULL;
4035 VOS_STATUS status = 0;
4036 v_U8_t staId = 0;
4037 v_U8_t *staMac = NULL;
4038
4039 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4040
4041 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4042 {
4043 pAdapter = pAdapterNode->pAdapter;
4044
4045 if( pAdapter )
4046 {
4047 hddLog(VOS_TRACE_LEVEL_INFO,
4048 "%s: Adapter with device mode %d exists",
4049 __func__, pAdapter->device_mode);
4050 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4051 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4052 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4053 {
4054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4055 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4056 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4057 {
4058 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4059 hddLog(VOS_TRACE_LEVEL_ERROR,
4060 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4061 "middle of WPS/EAPOL exchange.", __func__,
4062 staMac[0], staMac[1], staMac[2],
4063 staMac[3], staMac[4], staMac[5]);
4064 return VOS_FALSE;
4065 }
4066 }
4067 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4068 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4069 {
4070 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4071 {
4072 if ((pAdapter->aStaInfo[staId].isUsed) &&
4073 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4074 {
4075 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4076
4077 hddLog(VOS_TRACE_LEVEL_ERROR,
4078 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4079 "middle of WPS/EAPOL exchange.", __func__,
4080 staMac[0], staMac[1], staMac[2],
4081 staMac[3], staMac[4], staMac[5]);
4082 return VOS_FALSE;
4083 }
4084 }
4085 }
4086 }
4087 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4088 pAdapterNode = pNext;
4089 }
4090 hddLog(VOS_TRACE_LEVEL_INFO,
4091 "%s: Scan allowed", __func__);
4092 return VOS_TRUE;
4093}
4094
4095/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004096 * FUNCTION: wlan_hdd_cfg80211_scan
4097 * this scan respond to scan trigger and update cfg80211 scan database
4098 * later, scan dump command can be used to recieve scan results
4099 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004100int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4101#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4102 struct net_device *dev,
4103#endif
4104 struct cfg80211_scan_request *request)
4105{
4106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4107 struct net_device *dev = request->wdev->netdev;
4108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4110 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4111 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4112 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4113 tCsrScanRequest scanRequest;
4114 tANI_U8 *channelList = NULL, i;
4115 v_U32_t scanId = 0;
4116 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004117 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004118#ifdef WLAN_FEATURE_P2P
4119 v_U8_t* pP2pIe = NULL;
4120#endif
4121
4122 ENTER();
4123
4124 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4125 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004126
4127 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4128 (eConnectionState_Connecting ==
4129 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
4130 {
4131 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004132 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4133 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004134 return -EBUSY;
4135 }
4136
Jeff Johnson295189b2012-06-20 16:38:30 -07004137#ifdef WLAN_BTAMP_FEATURE
4138 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004139 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004141 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004142 "%s: No scanning when AMP is on", __func__);
4143 return -EOPNOTSUPP;
4144 }
4145#endif
4146 //Scan on any other interface is not supported.
4147 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
4148 {
4149 hddLog(VOS_TRACE_LEVEL_ERROR,
4150 "%s: Not scanning on device_mode = %d",
4151 __func__, pAdapter->device_mode);
4152 return -EOPNOTSUPP;
4153 }
4154
4155 if (TRUE == pScanInfo->mScanPending)
4156 {
4157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
4158 return -EBUSY;
4159 }
4160
4161 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4162 {
4163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4164 "%s:LOGP in Progress. Ignore!!!", __func__);
4165 return -EAGAIN;
4166 }
4167
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004168 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4169 {
4170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4171 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4172 return -EAGAIN;
4173 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004174 //Don't Allow Scan and return busy if Remain On
4175 //Channel and action frame is pending
4176 //Otherwise Cancel Remain On Channel and allow Scan
4177 //If no action frame pending
4178 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
4179 {
4180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4181 return -EBUSY;
4182 }
4183
Jeff Johnson295189b2012-06-20 16:38:30 -07004184 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4185 {
4186 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004187 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 return -EAGAIN;
4189 }
4190 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4191 {
4192 hddLog(VOS_TRACE_LEVEL_WARN,
4193 "%s: MAX TM Level Scan not allowed", __func__);
4194 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4195 return -EBUSY;
4196 }
4197 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4198
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004199 /* Check if scan is allowed at this point of time.
4200 */
4201 if (!hdd_isScanAllowed(pHddCtx))
4202 {
4203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4204 return -EBUSY;
4205 }
4206
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4208
4209 if (NULL != request)
4210 {
4211 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4212 (int)request->n_ssids);
4213
4214 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4215 * Becasue of this, driver is assuming that this is not wildcard scan and so
4216 * is not aging out the scan results.
4217 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004218 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 {
4220 request->n_ssids = 0;
4221 }
4222
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004223 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004224 {
4225 tCsrSSIDInfo *SsidInfo;
4226 int j;
4227 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4228 /* Allocate num_ssid tCsrSSIDInfo structure */
4229 SsidInfo = scanRequest.SSIDs.SSIDList =
4230 ( tCsrSSIDInfo *)vos_mem_malloc(
4231 request->n_ssids*sizeof(tCsrSSIDInfo));
4232
4233 if(NULL == scanRequest.SSIDs.SSIDList)
4234 {
4235 hddLog(VOS_TRACE_LEVEL_ERROR,
4236 "memory alloc failed SSIDInfo buffer");
4237 return -ENOMEM;
4238 }
4239
4240 /* copy all the ssid's and their length */
4241 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4242 {
4243 /* get the ssid length */
4244 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4245 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4246 SsidInfo->SSID.length);
4247 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4248 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4249 j, SsidInfo->SSID.ssId);
4250 }
4251 /* set the scan type to active */
4252 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4253 }
4254 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4255 {
4256 /* set the scan type to active */
4257 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4258 }
4259 else
4260 {
4261 /*Set the scan type to default type, in this case it is ACTIVE*/
4262 scanRequest.scanType = pScanInfo->scan_mode;
4263 }
4264 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4265 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4266 }
4267 else
4268 {
4269 /* set the scan type to active */
4270 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4271 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4272
4273 /* set min and max channel time to zero */
4274 scanRequest.minChnTime = 0;
4275 scanRequest.maxChnTime = 0;
4276 }
4277
4278 /* set BSSType to default type */
4279 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4280
4281 /*TODO: scan the requested channels only*/
4282
4283 /*Right now scanning all the channels */
4284 if( request )
4285 {
4286 if( request->n_channels )
4287 {
4288 channelList = vos_mem_malloc( request->n_channels );
4289 if( NULL == channelList )
4290 {
4291 status = -ENOMEM;
4292 goto free_mem;
4293 }
4294
4295 for( i = 0 ; i < request->n_channels ; i++ )
4296 channelList[i] = request->channels[i]->hw_value;
4297 }
4298
4299 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4300 scanRequest.ChannelInfo.ChannelList = channelList;
4301
4302 /* set requestType to full scan */
4303 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004304
4305 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4306 * search (Flush on both full scan and social scan but not on single
4307 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4308 */
4309
4310 /* Supplicant does single channel scan after 8-way handshake
4311 * and in that case driver shoudnt flush scan results. If
4312 * driver flushes the scan results here and unfortunately if
4313 * the AP doesnt respond to our probe req then association
4314 * fails which is not desired
4315 */
4316
4317 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4318 {
4319 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4320 pAdapter->sessionId );
4321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004322
4323 if( request->ie_len )
4324 {
4325 /* save this for future association (join requires this) */
4326 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4327 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4328 pScanInfo->scanAddIE.length = request->ie_len;
4329
4330 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004331 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4332 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004333 )
4334 {
4335 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4336 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4337 }
4338
4339 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4340 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4341
4342#ifdef WLAN_FEATURE_P2P
4343 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4344 request->ie_len);
4345 if (pP2pIe != NULL)
4346 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004347#ifdef WLAN_FEATURE_P2P_DEBUG
4348 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4349 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4350 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4351 {
4352 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4353 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4354 "Go nego completed to Connection is started");
4355 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4356 "for 8way Handshake");
4357 }
4358 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4359 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4360 {
4361 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4362 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4363 "Disconnected state to Connection is started");
4364 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4365 "for 4way Handshake");
4366 }
4367#endif
4368
Jeff Johnsone7245742012-09-05 17:12:55 -07004369 /* no_cck will be set during p2p find to disable 11b rates */
4370 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004371 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 hddLog(VOS_TRACE_LEVEL_INFO,
4373 "%s: This is a P2P Search", __func__);
4374 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004375
Jeff Johnsone7245742012-09-05 17:12:55 -07004376 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4377 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004378 /* set requestType to P2P Discovery */
4379 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004380 }
4381
4382 /*
4383 Skip Dfs Channel in case of P2P Search
4384 if it is set in ini file
4385 */
4386 if(cfg_param->skipDfsChnlInP2pSearch)
4387 {
4388 scanRequest.skipDfsChnlInP2pSearch = 1;
4389 }
4390 else
4391 {
4392 scanRequest.skipDfsChnlInP2pSearch = 0;
4393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004394
Jeff Johnson295189b2012-06-20 16:38:30 -07004395 }
4396 }
4397#endif
4398 }
4399 }
4400
4401 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4402
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004403 /* acquire the wakelock to avoid the apps suspend during the scan. To
4404 * address the following issues.
4405 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4406 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4407 * for long time, this result in apps running at full power for long time.
4408 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4409 * be stuck in full power because of resume BMPS
4410 */
4411 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004412
4413 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004414 pAdapter->sessionId, &scanRequest, &scanId,
4415 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004416
Jeff Johnson295189b2012-06-20 16:38:30 -07004417 if (eHAL_STATUS_SUCCESS != status)
4418 {
4419 hddLog(VOS_TRACE_LEVEL_ERROR,
4420 "%s: sme_ScanRequest returned error %d", __func__, status);
4421 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004422 if(eHAL_STATUS_RESOURCES == status)
4423 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004424 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 -07004425 status = -EBUSY;
4426 } else {
4427 status = -EIO;
4428 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004429 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 goto free_mem;
4431 }
4432
4433 pScanInfo->mScanPending = TRUE;
4434 pAdapter->request = request;
4435 pScanInfo->scanId = scanId;
4436
4437 complete(&pScanInfo->scan_req_completion_event);
4438
4439free_mem:
4440 if( scanRequest.SSIDs.SSIDList )
4441 {
4442 vos_mem_free(scanRequest.SSIDs.SSIDList);
4443 }
4444
4445 if( channelList )
4446 vos_mem_free( channelList );
4447
4448 EXIT();
4449
4450 return status;
4451}
4452
4453/*
4454 * FUNCTION: wlan_hdd_cfg80211_connect_start
4455 * This function is used to start the association process
4456 */
4457int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004458 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004459{
4460 int status = 0;
4461 hdd_wext_state_t *pWextState;
4462 v_U32_t roamId;
4463 tCsrRoamProfile *pRoamProfile;
4464 eMib_dot11DesiredBssType connectedBssType;
4465 eCsrAuthType RSNAuthType;
4466
4467 ENTER();
4468
4469 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4470
4471 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4472 {
4473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4474 return -EINVAL;
4475 }
4476
4477 pRoamProfile = &pWextState->roamProfile;
4478
4479 if (pRoamProfile)
4480 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004481 int ret = 0;
4482 hdd_station_ctx_t *pHddStaCtx;
4483 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4484 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4485
4486 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4487 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4488 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004489 {
4490 /* Issue disconnect to CSR */
4491 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4492 if( eHAL_STATUS_SUCCESS ==
4493 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4494 pAdapter->sessionId,
4495 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4496 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004497 ret = wait_for_completion_interruptible_timeout(
4498 &pAdapter->disconnect_comp_var,
4499 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4500 if (0 == ret)
4501 {
4502 VOS_ASSERT(0);
4503 }
4504 }
4505 }
4506 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4507 {
4508 ret = wait_for_completion_interruptible_timeout(
4509 &pAdapter->disconnect_comp_var,
4510 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4511 if (0 == ret)
4512 {
4513 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004514 }
4515 }
4516
4517 if (HDD_WMM_USER_MODE_NO_QOS ==
4518 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4519 {
4520 /*QoS not enabled in cfg file*/
4521 pRoamProfile->uapsd_mask = 0;
4522 }
4523 else
4524 {
4525 /*QoS enabled, update uapsd mask from cfg file*/
4526 pRoamProfile->uapsd_mask =
4527 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4528 }
4529
4530 pRoamProfile->SSIDs.numOfSSIDs = 1;
4531 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4532 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4533 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4534 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4535 ssid, ssid_len);
4536
4537 if (bssid)
4538 {
4539 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4540 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4541 WNI_CFG_BSSID_LEN);
4542 /* Save BSSID in seperate variable as well, as RoamProfile
4543 BSSID is getting zeroed out in the association process. And in
4544 case of join failure we should send valid BSSID to supplicant
4545 */
4546 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4547 WNI_CFG_BSSID_LEN);
4548 }
4549
4550 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4551 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4552 {
4553 /*set gen ie*/
4554 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4555 /*set auth*/
4556 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4557 }
4558 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4559 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4560 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4561 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4562 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4563 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4564 )
4565 {
4566 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4567 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4568 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4569 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4570 eCSR_AUTH_TYPE_AUTOSWITCH;
4571 pWextState->roamProfile.AuthType.authType[0] =
4572 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4573 }
4574#ifdef FEATURE_WLAN_WAPI
4575 if (pAdapter->wapi_info.nWapiMode)
4576 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004577 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004578 switch (pAdapter->wapi_info.wapiAuthMode)
4579 {
4580 case WAPI_AUTH_MODE_PSK:
4581 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004582 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 pAdapter->wapi_info.wapiAuthMode);
4584 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4585 break;
4586 }
4587 case WAPI_AUTH_MODE_CERT:
4588 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004589 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004590 pAdapter->wapi_info.wapiAuthMode);
4591 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4592 break;
4593 }
4594 } // End of switch
4595 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4596 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4597 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004598 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004599 pRoamProfile->AuthType.numEntries = 1;
4600 pRoamProfile->EncryptionType.numEntries = 1;
4601 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4602 pRoamProfile->mcEncryptionType.numEntries = 1;
4603 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4604 }
4605 }
4606#endif /* FEATURE_WLAN_WAPI */
4607 pRoamProfile->csrPersona = pAdapter->device_mode;
4608
Jeff Johnson32d95a32012-09-10 13:15:23 -07004609 if( operatingChannel )
4610 {
4611 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4612 pRoamProfile->ChannelInfo.numOfChannels = 1;
4613 }
4614
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004615 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4616 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4617 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4618 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004619 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4620 */
4621 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4622 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4623 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004624
Jeff Johnson295189b2012-06-20 16:38:30 -07004625 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4626 pAdapter->sessionId, pRoamProfile, &roamId);
4627
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004628 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304629 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4630
4631 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4633 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4634 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304635 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004636 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304637 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004638
4639 pRoamProfile->ChannelInfo.ChannelList = NULL;
4640 pRoamProfile->ChannelInfo.numOfChannels = 0;
4641
Jeff Johnson295189b2012-06-20 16:38:30 -07004642 }
4643 else
4644 {
4645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4646 return -EINVAL;
4647 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004648 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004649 return status;
4650}
4651
4652/*
4653 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4654 * This function is used to set the authentication type (OPEN/SHARED).
4655 *
4656 */
4657static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4658 enum nl80211_auth_type auth_type)
4659{
4660 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4661 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4662
4663 ENTER();
4664
4665 /*set authentication type*/
4666 switch (auth_type)
4667 {
4668 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4669 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004670#ifdef WLAN_FEATURE_VOWIFI_11R
4671 case NL80211_AUTHTYPE_FT:
4672#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004673 hddLog(VOS_TRACE_LEVEL_INFO,
4674 "%s: set authentication type to OPEN", __func__);
4675 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4676 break;
4677
4678 case NL80211_AUTHTYPE_SHARED_KEY:
4679 hddLog(VOS_TRACE_LEVEL_INFO,
4680 "%s: set authentication type to SHARED", __func__);
4681 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4682 break;
4683#ifdef FEATURE_WLAN_CCX
4684 case NL80211_AUTHTYPE_NETWORK_EAP:
4685 hddLog(VOS_TRACE_LEVEL_INFO,
4686 "%s: set authentication type to CCKM WPA", __func__);
4687 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4688 break;
4689#endif
4690
4691
4692 default:
4693 hddLog(VOS_TRACE_LEVEL_ERROR,
4694 "%s: Unsupported authentication type %d", __func__,
4695 auth_type);
4696 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4697 return -EINVAL;
4698 }
4699
4700 pWextState->roamProfile.AuthType.authType[0] =
4701 pHddStaCtx->conn_info.authType;
4702 return 0;
4703}
4704
4705/*
4706 * FUNCTION: wlan_hdd_set_akm_suite
4707 * This function is used to set the key mgmt type(PSK/8021x).
4708 *
4709 */
4710static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4711 u32 key_mgmt
4712 )
4713{
4714 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4715 ENTER();
4716
4717 /*set key mgmt type*/
4718 switch(key_mgmt)
4719 {
4720 case WLAN_AKM_SUITE_PSK:
4721 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4722 __func__);
4723 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4724 break;
4725
4726 case WLAN_AKM_SUITE_8021X:
4727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4728 __func__);
4729 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4730 break;
4731#ifdef FEATURE_WLAN_CCX
4732#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4733#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4734 case WLAN_AKM_SUITE_CCKM:
4735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4736 __func__);
4737 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4738 break;
4739#endif
4740
4741 default:
4742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4743 __func__, key_mgmt);
4744 return -EINVAL;
4745
4746 }
4747 return 0;
4748}
4749
4750/*
4751 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4752 * This function is used to set the encryption type
4753 * (NONE/WEP40/WEP104/TKIP/CCMP).
4754 */
4755static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4756 u32 cipher,
4757 bool ucast
4758 )
4759{
4760 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4761 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4762 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4763
4764 ENTER();
4765
4766 if (!cipher)
4767 {
4768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4769 __func__, cipher);
4770 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4771 }
4772 else
4773 {
4774
4775 /*set encryption method*/
4776 switch (cipher)
4777 {
4778 case IW_AUTH_CIPHER_NONE:
4779 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4780 break;
4781
4782 case WLAN_CIPHER_SUITE_WEP40:
4783 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4784 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4785 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4786 else
4787 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4788 break;
4789
4790 case WLAN_CIPHER_SUITE_WEP104:
4791 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4792 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4793 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4794 else
4795 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4796 break;
4797
4798 case WLAN_CIPHER_SUITE_TKIP:
4799 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4800 break;
4801
4802 case WLAN_CIPHER_SUITE_CCMP:
4803 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4804 break;
4805#ifdef FEATURE_WLAN_WAPI
4806 case WLAN_CIPHER_SUITE_SMS4:
4807 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4808 break;
4809#endif
4810
4811#ifdef FEATURE_WLAN_CCX
4812 case WLAN_CIPHER_SUITE_KRK:
4813 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4814 break;
4815#endif
4816 default:
4817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4818 __func__, cipher);
4819 return -EOPNOTSUPP;
4820 }
4821 }
4822
4823 if (ucast)
4824 {
4825 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4826 __func__, encryptionType);
4827 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4828 pWextState->roamProfile.EncryptionType.numEntries = 1;
4829 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4830 encryptionType;
4831 }
4832 else
4833 {
4834 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4835 __func__, encryptionType);
4836 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4837 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4838 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4839 }
4840
4841 return 0;
4842}
4843
4844
4845/*
4846 * FUNCTION: wlan_hdd_cfg80211_set_ie
4847 * This function is used to parse WPA/RSN IE's.
4848 */
4849int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4850 u8 *ie,
4851 size_t ie_len
4852 )
4853{
4854 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4855 u8 *genie = ie;
4856 v_U16_t remLen = ie_len;
4857#ifdef FEATURE_WLAN_WAPI
4858 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4859 u16 *tmp;
4860 v_U16_t akmsuiteCount;
4861 int *akmlist;
4862#endif
4863 ENTER();
4864
4865 /* clear previous assocAddIE */
4866 pWextState->assocAddIE.length = 0;
4867 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4868
4869 while (remLen >= 2)
4870 {
4871 v_U16_t eLen = 0;
4872 v_U8_t elementId;
4873 elementId = *genie++;
4874 eLen = *genie++;
4875 remLen -= 2;
4876
4877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4878 __func__, elementId, eLen);
4879
4880 switch ( elementId )
4881 {
4882 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004883 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 -07004884 {
4885 hddLog(VOS_TRACE_LEVEL_ERROR,
4886 "%s: Invalid WPA IE", __func__);
4887 return -EINVAL;
4888 }
4889 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4890 {
4891 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4892 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4893 __func__, eLen + 2);
4894
4895 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4896 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004897 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4898 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 VOS_ASSERT(0);
4900 return -ENOMEM;
4901 }
4902 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4903 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4904 pWextState->assocAddIE.length += eLen + 2;
4905
4906 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4907 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4908 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4909 }
4910 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4911 {
4912 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4913 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4914 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4915 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4916 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4917 }
4918#ifdef WLAN_FEATURE_P2P
4919 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4920 P2P_OUI_TYPE_SIZE))
4921 /*Consider P2P IE, only for P2P Client */
4922 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4923 {
4924 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4925 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4926 __func__, eLen + 2);
4927
4928 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4929 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004930 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4931 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 VOS_ASSERT(0);
4933 return -ENOMEM;
4934 }
4935 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4936 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4937 pWextState->assocAddIE.length += eLen + 2;
4938
4939 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4940 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4941 }
4942#endif
4943#ifdef WLAN_FEATURE_WFD
4944 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4945 WFD_OUI_TYPE_SIZE))
4946 /*Consider WFD IE, only for P2P Client */
4947 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4948 {
4949 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4950 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4951 __func__, eLen + 2);
4952
4953 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4954 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004955 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4956 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004957 VOS_ASSERT(0);
4958 return -ENOMEM;
4959 }
4960 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4961 // WPS IE + P2P IE + WFD IE
4962 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4963 pWextState->assocAddIE.length += eLen + 2;
4964
4965 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4966 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4967 }
4968#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004969 /* Appending HS 2.0 Indication Element in Assiciation Request */
4970 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004971 HS20_OUI_TYPE_SIZE)) )
4972 {
4973 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4974 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4975 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004976
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004977 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4978 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004979 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4980 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004981 VOS_ASSERT(0);
4982 return -ENOMEM;
4983 }
4984 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4985 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004986
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004987 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4988 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4989 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004990
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 break;
4992 case DOT11F_EID_RSN:
4993 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4994 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4995 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
4996 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
4997 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
4998 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004999 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5000 case DOT11F_EID_EXTCAP:
5001 {
5002 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5003 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5004 __func__, eLen + 2);
5005
5006 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5007 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005008 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5009 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005010 VOS_ASSERT(0);
5011 return -ENOMEM;
5012 }
5013 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5014 pWextState->assocAddIE.length += eLen + 2;
5015
5016 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5017 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5018 break;
5019 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005020#ifdef FEATURE_WLAN_WAPI
5021 case WLAN_EID_WAPI:
5022 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5023 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5024 pAdapter->wapi_info.nWapiMode);
5025 tmp = (u16 *)ie;
5026 tmp = tmp + 2; // Skip element Id and Len, Version
5027 akmsuiteCount = WPA_GET_LE16(tmp);
5028 tmp = tmp + 1;
5029 akmlist = (int *)(tmp);
5030 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5031 {
5032 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5033 }
5034 else
5035 {
5036 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5037 VOS_ASSERT(0);
5038 return -EINVAL;
5039 }
5040
5041 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5042 {
5043 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005044 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005045 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5046 }
5047 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5048 {
5049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005050 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5052 }
5053 break;
5054#endif
5055 default:
5056 hddLog (VOS_TRACE_LEVEL_ERROR,
5057 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005058 /* when Unknown IE is received we should break and continue
5059 * to the next IE in the buffer instead we were returning
5060 * so changing this to break */
5061 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005062 }
5063 genie += eLen;
5064 remLen -= eLen;
5065 }
5066 EXIT();
5067 return 0;
5068}
5069
5070/*
5071 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5072 * This function is used to initialize the security
5073 * parameters during connect operation.
5074 */
5075int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5076 struct cfg80211_connect_params *req
5077 )
5078{
5079 int status = 0;
5080 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5081 ENTER();
5082
5083 /*set wpa version*/
5084 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5085
5086 if (req->crypto.wpa_versions)
5087 {
5088 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5089 && ( (req->ie_len)
5090 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5091 // Make sure that it is including a WPA IE.
5092 /* Currently NL is putting WPA version 1 even for open,
5093 * since p2p ie is also put in same buffer.
5094 * */
5095 {
5096 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5097 }
5098 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5099 {
5100 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5101 }
5102 }
5103
5104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5105 pWextState->wpaVersion);
5106
5107 /*set authentication type*/
5108 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5109
5110 if (0 > status)
5111 {
5112 hddLog(VOS_TRACE_LEVEL_ERROR,
5113 "%s: failed to set authentication type ", __func__);
5114 return status;
5115 }
5116
5117 /*set key mgmt type*/
5118 if (req->crypto.n_akm_suites)
5119 {
5120 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5121 if (0 > status)
5122 {
5123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5124 __func__);
5125 return status;
5126 }
5127 }
5128
5129 /*set pairwise cipher type*/
5130 if (req->crypto.n_ciphers_pairwise)
5131 {
5132 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5133 req->crypto.ciphers_pairwise[0], true);
5134 if (0 > status)
5135 {
5136 hddLog(VOS_TRACE_LEVEL_ERROR,
5137 "%s: failed to set unicast cipher type", __func__);
5138 return status;
5139 }
5140 }
5141 else
5142 {
5143 /*Reset previous cipher suite to none*/
5144 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5145 if (0 > status)
5146 {
5147 hddLog(VOS_TRACE_LEVEL_ERROR,
5148 "%s: failed to set unicast cipher type", __func__);
5149 return status;
5150 }
5151 }
5152
5153 /*set group cipher type*/
5154 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5155 false);
5156
5157 if (0 > status)
5158 {
5159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5160 __func__);
5161 return status;
5162 }
5163
5164 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5165 if (req->ie_len)
5166 {
5167 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5168 if ( 0 > status)
5169 {
5170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5171 __func__);
5172 return status;
5173 }
5174 }
5175
5176 /*incase of WEP set default key information*/
5177 if (req->key && req->key_len)
5178 {
5179 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5180 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5181 )
5182 {
5183 if ( IW_AUTH_KEY_MGMT_802_1X
5184 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5185 {
5186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5187 __func__);
5188 return -EOPNOTSUPP;
5189 }
5190 else
5191 {
5192 u8 key_len = req->key_len;
5193 u8 key_idx = req->key_idx;
5194
5195 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5196 && (CSR_MAX_NUM_KEY > key_idx)
5197 )
5198 {
5199 hddLog(VOS_TRACE_LEVEL_INFO,
5200 "%s: setting default wep key, key_idx = %hu key_len %hu",
5201 __func__, key_idx, key_len);
5202 vos_mem_copy(
5203 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5204 req->key, key_len);
5205 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5206 (u8)key_len;
5207 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5208 }
5209 }
5210 }
5211 }
5212
5213 return status;
5214}
5215
5216/*
5217 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5218 * This function is used to initialize the security
5219 * parameters during connect operation.
5220 */
5221static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5222 struct net_device *ndev,
5223 struct cfg80211_connect_params *req
5224 )
5225{
5226 int status = 0;
5227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5228 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5229 hdd_context_t *pHddCtx = NULL;
5230
5231 ENTER();
5232
5233 hddLog(VOS_TRACE_LEVEL_INFO,
5234 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5235
5236 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5237 {
5238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5239 "%s:LOGP in Progress. Ignore!!!", __func__);
5240 return -EAGAIN;
5241 }
5242
5243#ifdef WLAN_BTAMP_FEATURE
5244 //Infra connect not supported when AMP traffic is on.
5245 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5246 {
5247 hddLog(VOS_TRACE_LEVEL_ERROR,
5248 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005249 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005250 }
5251#endif
5252 /*initialise security parameters*/
5253 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5254
5255 if ( 0 > status)
5256 {
5257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5258 __func__);
5259 return status;
5260 }
5261
5262 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005263 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005264 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5265 (vos_concurrent_sessions_running()))
5266 {
5267 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5268
5269 if (NULL != pVosContext)
5270 {
5271 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5272 if(NULL != pHddCtx)
5273 {
5274 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5275 }
5276 }
5277 }
5278
Mohit Khanna765234a2012-09-11 15:08:35 -07005279 if ( req->channel )
5280 {
5281 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5282 req->ssid_len, req->bssid,
5283 req->channel->hw_value);
5284 }
5285 else
5286 {
5287 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5288 req->ssid_len, req->bssid,
5289 0);
5290 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005291
5292 if (0 > status)
5293 {
5294 //ReEnable BMPS if disabled
5295 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5296 (NULL != pHddCtx))
5297 {
5298 //ReEnable Bmps and Imps back
5299 hdd_enable_bmps_imps(pHddCtx);
5300 }
5301
5302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5303 return status;
5304 }
5305 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5306 EXIT();
5307 return status;
5308}
5309
5310
5311/*
5312 * FUNCTION: wlan_hdd_cfg80211_disconnect
5313 * This function is used to issue a disconnect request to SME
5314 */
5315static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5316 struct net_device *dev,
5317 u16 reason
5318 )
5319{
5320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5321 tCsrRoamProfile *pRoamProfile =
5322 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5323 int status = 0;
5324 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5325
5326 ENTER();
5327
5328 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5329 __func__,pAdapter->device_mode);
5330
5331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5332 __func__, reason);
5333
5334 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5335 {
5336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5337 "%s:LOGP in Progress. Ignore!!!",__func__);
5338 return -EAGAIN;
5339 }
5340 if (NULL != pRoamProfile)
5341 {
5342 /*issue disconnect request to SME, if station is in connected state*/
5343 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5344 {
5345 eCsrRoamDisconnectReason reasonCode =
5346 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5347 switch(reason)
5348 {
5349 case WLAN_REASON_MIC_FAILURE:
5350 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5351 break;
5352
5353 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5354 case WLAN_REASON_DISASSOC_AP_BUSY:
5355 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5356 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5357 break;
5358
5359 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5360 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5361 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5362 break;
5363
5364 case WLAN_REASON_DEAUTH_LEAVING:
5365 default:
5366 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5367 break;
5368 }
5369 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5370 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5371 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5372
5373 /*issue disconnect*/
5374 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5375 pAdapter->sessionId, reasonCode);
5376
5377 if ( 0 != status)
5378 {
5379 hddLog(VOS_TRACE_LEVEL_ERROR,
5380 "%s csrRoamDisconnect failure, returned %d \n",
5381 __func__, (int)status );
5382 return -EINVAL;
5383 }
5384
5385 wait_for_completion_interruptible_timeout(
5386 &pAdapter->disconnect_comp_var,
5387 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5388
5389
5390 /*stop tx queues*/
5391 netif_tx_disable(dev);
5392 netif_carrier_off(dev);
5393 }
5394 }
5395 else
5396 {
5397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5398 }
5399
5400 return status;
5401}
5402
5403/*
5404 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5405 * This function is used to initialize the security
5406 * settings in IBSS mode.
5407 */
5408static int wlan_hdd_cfg80211_set_privacy_ibss(
5409 hdd_adapter_t *pAdapter,
5410 struct cfg80211_ibss_params *params
5411 )
5412{
5413 int status = 0;
5414 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5415 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5416 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5417
5418 ENTER();
5419
5420 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5421
5422 if (params->ie_len && ( NULL != params->ie) )
5423 {
5424 if (WLAN_EID_RSN == params->ie[0])
5425 {
5426 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5427 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5428 }
5429 else
5430 {
5431 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5432 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5433 }
5434 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5435
5436 if (0 > status)
5437 {
5438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5439 __func__);
5440 return status;
5441 }
5442 }
5443
5444 pWextState->roamProfile.AuthType.authType[0] =
5445 pHddStaCtx->conn_info.authType =
5446 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5447
5448 if (params->privacy)
5449 {
5450 /* Security enabled IBSS, At this time there is no information available
5451 * about the security paramters, so initialise the encryption type to
5452 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5453 * The correct security parameters will be updated later in
5454 * wlan_hdd_cfg80211_add_key */
5455 /* Hal expects encryption type to be set inorder
5456 *enable privacy bit in beacons */
5457
5458 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5459 }
5460
5461 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5462 pWextState->roamProfile.EncryptionType.numEntries = 1;
5463 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5464
5465 return status;
5466}
5467
5468/*
5469 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5470 * This function is used to create/join an IBSS
5471 */
5472static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5473 struct net_device *dev,
5474 struct cfg80211_ibss_params *params
5475 )
5476{
5477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5478 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5479 tCsrRoamProfile *pRoamProfile;
5480 int status;
5481 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5482
5483 ENTER();
5484
5485 hddLog(VOS_TRACE_LEVEL_INFO,
5486 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5487
5488 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5489 {
5490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5491 "%s:LOGP in Progress. Ignore!!!", __func__);
5492 return -EAGAIN;
5493 }
5494
5495 if (NULL == pWextState)
5496 {
5497 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5498 __func__);
5499 return -EIO;
5500 }
5501
5502 pRoamProfile = &pWextState->roamProfile;
5503
5504 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5505 {
5506 hddLog (VOS_TRACE_LEVEL_ERROR,
5507 "%s Interface type is not set to IBSS \n", __func__);
5508 return -EINVAL;
5509 }
5510
5511 /* Set Channel */
5512 if (NULL != params->channel)
5513 {
5514 u8 channelNum;
5515 if (IEEE80211_BAND_5GHZ == params->channel->band)
5516 {
5517 hddLog(VOS_TRACE_LEVEL_ERROR,
5518 "%s: IBSS join is called with unsupported band %d",
5519 __func__, params->channel->band);
5520 return -EOPNOTSUPP;
5521 }
5522
5523 /* Get channel number */
5524 channelNum =
5525 ieee80211_frequency_to_channel(params->channel->center_freq);
5526
5527 /*TODO: use macro*/
5528 if (14 >= channelNum)
5529 {
5530 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5531 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5532 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5533 int indx;
5534
5535 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5536 validChan, &numChans))
5537 {
5538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5539 __func__);
5540 return -EOPNOTSUPP;
5541 }
5542
5543 for (indx = 0; indx < numChans; indx++)
5544 {
5545 if (channelNum == validChan[indx])
5546 {
5547 break;
5548 }
5549 }
5550 if (indx >= numChans)
5551 {
5552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5553 __func__, channelNum);
5554 return -EINVAL;
5555 }
5556 /* Set the Operational Channel */
5557 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5558 channelNum);
5559 pRoamProfile->ChannelInfo.numOfChannels = 1;
5560 pHddStaCtx->conn_info.operationChannel = channelNum;
5561 pRoamProfile->ChannelInfo.ChannelList =
5562 &pHddStaCtx->conn_info.operationChannel;
5563 }
5564 else
5565 {
5566 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5567 __func__, channelNum);
5568 return -EINVAL;
5569 }
5570 }
5571
5572 /* Initialize security parameters */
5573 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5574 if (status < 0)
5575 {
5576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5577 __func__);
5578 return status;
5579 }
5580
5581 /* Issue connect start */
5582 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005583 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005584
5585 if (0 > status)
5586 {
5587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5588 return status;
5589 }
5590
5591 return 0;
5592}
5593
5594/*
5595 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5596 * This function is used to leave an IBSS
5597 */
5598static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5599 struct net_device *dev
5600 )
5601{
5602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5603 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5604 tCsrRoamProfile *pRoamProfile;
5605
5606 ENTER();
5607
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005608 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5609 {
5610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5611 "%s:LOGP in Progress. Ignore!!!", __func__);
5612 return -EAGAIN;
5613 }
5614
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5616 if (NULL == pWextState)
5617 {
5618 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5619 __func__);
5620 return -EIO;
5621 }
5622
5623 pRoamProfile = &pWextState->roamProfile;
5624
5625 /* Issue disconnect only if interface type is set to IBSS */
5626 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5627 {
5628 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5629 __func__);
5630 return -EINVAL;
5631 }
5632
5633 /* Issue Disconnect request */
5634 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5635 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5636 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5637
5638 return 0;
5639}
5640
5641/*
5642 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5643 * This function is used to set the phy parameters
5644 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5645 */
5646static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5647 u32 changed)
5648{
5649 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5650 tHalHandle hHal = pHddCtx->hHal;
5651
5652 ENTER();
5653
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005654 if ( pHddCtx->isLogpInProgress )
5655 {
5656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5657 "%s:LOGP in Progress. Ignore!!!", __func__);
5658 return -EAGAIN;
5659 }
5660
Jeff Johnson295189b2012-06-20 16:38:30 -07005661 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5662 {
5663 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5664 WNI_CFG_RTS_THRESHOLD_STAMAX :
5665 wiphy->rts_threshold;
5666
5667 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5668 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5669 {
5670 hddLog(VOS_TRACE_LEVEL_ERROR,
5671 "%s: Invalid RTS Threshold value %hu",
5672 __func__, rts_threshold);
5673 return -EINVAL;
5674 }
5675
5676 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5677 rts_threshold, ccmCfgSetCallback,
5678 eANI_BOOLEAN_TRUE))
5679 {
5680 hddLog(VOS_TRACE_LEVEL_ERROR,
5681 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5682 __func__, rts_threshold);
5683 return -EIO;
5684 }
5685
5686 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5687 rts_threshold);
5688 }
5689
5690 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5691 {
5692 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5693 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5694 wiphy->frag_threshold;
5695
5696 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5697 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5698 {
5699 hddLog(VOS_TRACE_LEVEL_ERROR,
5700 "%s: Invalid frag_threshold value %hu", __func__,
5701 frag_threshold);
5702 return -EINVAL;
5703 }
5704
5705 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5706 frag_threshold, ccmCfgSetCallback,
5707 eANI_BOOLEAN_TRUE))
5708 {
5709 hddLog(VOS_TRACE_LEVEL_ERROR,
5710 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5711 __func__, frag_threshold);
5712 return -EIO;
5713 }
5714
5715 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5716 frag_threshold);
5717 }
5718
5719 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5720 || (changed & WIPHY_PARAM_RETRY_LONG))
5721 {
5722 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5723 wiphy->retry_short :
5724 wiphy->retry_long;
5725
5726 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5727 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5728 {
5729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5730 __func__, retry_value);
5731 return -EINVAL;
5732 }
5733
5734 if (changed & WIPHY_PARAM_RETRY_SHORT)
5735 {
5736 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5737 retry_value, ccmCfgSetCallback,
5738 eANI_BOOLEAN_TRUE))
5739 {
5740 hddLog(VOS_TRACE_LEVEL_ERROR,
5741 "%s: ccmCfgSetInt failed for long retry count %hu",
5742 __func__, retry_value);
5743 return -EIO;
5744 }
5745 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5746 __func__, retry_value);
5747 }
5748 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5749 {
5750 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5751 retry_value, ccmCfgSetCallback,
5752 eANI_BOOLEAN_TRUE))
5753 {
5754 hddLog(VOS_TRACE_LEVEL_ERROR,
5755 "%s: ccmCfgSetInt failed for short retry count %hu",
5756 __func__, retry_value);
5757 return -EIO;
5758 }
5759 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5760 __func__, retry_value);
5761 }
5762 }
5763
5764 return 0;
5765}
5766
5767/*
5768 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5769 * This function is used to set the txpower
5770 */
5771static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5772#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5773 enum tx_power_setting type,
5774#else
5775 enum nl80211_tx_power_setting type,
5776#endif
5777 int dbm)
5778{
5779 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5780 tHalHandle hHal = pHddCtx->hHal;
5781 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5782 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5783
5784 ENTER();
5785
5786 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5787 dbm, ccmCfgSetCallback,
5788 eANI_BOOLEAN_TRUE))
5789 {
5790 hddLog(VOS_TRACE_LEVEL_ERROR,
5791 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5792 return -EIO;
5793 }
5794
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005795 if ( pHddCtx->isLogpInProgress )
5796 {
5797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5798 "%s:LOGP in Progress. Ignore!!!", __func__);
5799 return -EAGAIN;
5800 }
5801
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5803 dbm);
5804
5805 switch(type)
5806 {
5807 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5808 /* Fall through */
5809 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5810 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5811 {
5812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5813 __func__);
5814 return -EIO;
5815 }
5816 break;
5817 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5819 __func__);
5820 return -EOPNOTSUPP;
5821 break;
5822 default:
5823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5824 __func__, type);
5825 return -EIO;
5826 }
5827
5828 return 0;
5829}
5830
5831/*
5832 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5833 * This function is used to read the txpower
5834 */
5835static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5836{
5837
5838 hdd_adapter_t *pAdapter;
5839 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5840
Jeff Johnsone7245742012-09-05 17:12:55 -07005841 ENTER();
5842
Jeff Johnson295189b2012-06-20 16:38:30 -07005843 if (NULL == pHddCtx)
5844 {
5845 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5846 *dbm = 0;
5847 return -ENOENT;
5848 }
5849
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005850 if ( pHddCtx->isLogpInProgress )
5851 {
5852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5853 "%s:LOGP in Progress. Ignore!!!", __func__);
5854 return -EAGAIN;
5855 }
5856
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5858 if (NULL == pAdapter)
5859 {
5860 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5861 return -ENOENT;
5862 }
5863
5864 wlan_hdd_get_classAstats(pAdapter);
5865 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5866
Jeff Johnsone7245742012-09-05 17:12:55 -07005867 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 return 0;
5869}
5870
5871static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5872 u8* mac, struct station_info *sinfo)
5873{
5874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5875 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5876 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5877 tANI_U8 rate_flags;
5878
5879 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5880 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5881 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5882
5883 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5884 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5885 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5886 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5887 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5888 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5889 tANI_U16 maxRate = 0;
5890 tANI_U16 myRate;
5891 tANI_U16 currentRate = 0;
5892 tANI_U8 maxSpeedMCS = 0;
5893 tANI_U8 maxMCSIdx = 0;
5894 tANI_U8 rateFlag = 1;
5895 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005896 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005897
Jeff Johnsone7245742012-09-05 17:12:55 -07005898 ENTER();
5899
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5901 (0 == ssidlen))
5902 {
5903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5904 " Invalid ssidlen, %d", __func__, ssidlen);
5905 /*To keep GUI happy*/
5906 return 0;
5907 }
5908
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005909 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5910 {
5911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5912 "%s:LOGP in Progress. Ignore!!!", __func__);
5913 return -EAGAIN;
5914 }
5915
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5917 sinfo->filled |= STATION_INFO_SIGNAL;
5918
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005919 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5921
5922 //convert to the UI units of 100kbps
5923 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5924
5925#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005926 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 -07005927 sinfo->signal,
5928 pCfg->reportMaxLinkSpeed,
5929 myRate,
5930 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005931 (int) pCfg->linkSpeedRssiMid,
5932 (int) pCfg->linkSpeedRssiLow,
5933 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005934#endif //LINKSPEED_DEBUG_ENABLED
5935
5936 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5937 {
5938 // we do not want to necessarily report the current speed
5939 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5940 {
5941 // report the max possible speed
5942 rssidx = 0;
5943 }
5944 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5945 {
5946 // report the max possible speed with RSSI scaling
5947 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5948 {
5949 // report the max possible speed
5950 rssidx = 0;
5951 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005952 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 {
5954 // report middle speed
5955 rssidx = 1;
5956 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005957 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5958 {
5959 // report middle speed
5960 rssidx = 2;
5961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 else
5963 {
5964 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005965 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 }
5967 }
5968 else
5969 {
5970 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5971 hddLog(VOS_TRACE_LEVEL_ERROR,
5972 "%s: Invalid value for reportMaxLinkSpeed: %u",
5973 __func__, pCfg->reportMaxLinkSpeed);
5974 rssidx = 0;
5975 }
5976
5977 maxRate = 0;
5978
5979 /* Get Basic Rate Set */
5980 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
5981 for (i = 0; i < ORLeng; i++)
5982 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005983 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 {
5985 /* Validate Rate Set */
5986 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
5987 {
5988 currentRate = supported_data_rate[j].supported_rate[rssidx];
5989 break;
5990 }
5991 }
5992 /* Update MAX rate */
5993 maxRate = (currentRate > maxRate)?currentRate:maxRate;
5994 }
5995
5996 /* Get Extended Rate Set */
5997 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
5998 for (i = 0; i < ERLeng; i++)
5999 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006000 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 {
6002 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6003 {
6004 currentRate = supported_data_rate[j].supported_rate[rssidx];
6005 break;
6006 }
6007 }
6008 /* Update MAX rate */
6009 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6010 }
6011
6012 /* Get MCS Rate Set -- but only if we are connected at MCS
6013 rates or if we are always reporting max speed or if we have
6014 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006015 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 {
6017 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
6018 rateFlag = 0;
6019 if (rate_flags & eHAL_TX_RATE_HT40)
6020 {
6021 rateFlag |= 1;
6022 }
6023 if (rate_flags & eHAL_TX_RATE_SGI)
6024 {
6025 rateFlag |= 2;
6026 }
6027
6028 for (i = 0; i < MCSLeng; i++)
6029 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006030 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6031 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 {
6033 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6034 {
6035 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6036 break;
6037 }
6038 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006039 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 {
6041 maxRate = currentRate;
6042 maxSpeedMCS = 1;
6043 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6044 }
6045 }
6046 }
6047
6048 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006049 if (((maxRate < myRate) && (0 == rssidx)) ||
6050 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 {
6052 maxRate = myRate;
6053 if (rate_flags & eHAL_TX_RATE_LEGACY)
6054 {
6055 maxSpeedMCS = 0;
6056 }
6057 else
6058 {
6059 maxSpeedMCS = 1;
6060 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6061 }
6062 }
6063
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006064 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006065 {
6066 sinfo->txrate.legacy = maxRate;
6067#ifdef LINKSPEED_DEBUG_ENABLED
6068 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6069#endif //LINKSPEED_DEBUG_ENABLED
6070 }
6071 else
6072 {
6073 sinfo->txrate.mcs = maxMCSIdx;
6074 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6075 if (rate_flags & eHAL_TX_RATE_SGI)
6076 {
6077 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6078 }
6079 if (rate_flags & eHAL_TX_RATE_HT40)
6080 {
6081 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6082 }
6083#ifdef LINKSPEED_DEBUG_ENABLED
6084 pr_info("Reporting MCS rate %d flags %x\n",
6085 sinfo->txrate.mcs,
6086 sinfo->txrate.flags );
6087#endif //LINKSPEED_DEBUG_ENABLED
6088 }
6089 }
6090 else
6091 {
6092 // report current rate instead of max rate
6093
6094 if (rate_flags & eHAL_TX_RATE_LEGACY)
6095 {
6096 //provide to the UI in units of 100kbps
6097 sinfo->txrate.legacy = myRate;
6098#ifdef LINKSPEED_DEBUG_ENABLED
6099 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6100#endif //LINKSPEED_DEBUG_ENABLED
6101 }
6102 else
6103 {
6104 //must be MCS
6105 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6106 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6107 if (rate_flags & eHAL_TX_RATE_SGI)
6108 {
6109 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6110 }
6111 if (rate_flags & eHAL_TX_RATE_HT40)
6112 {
6113 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6114 }
6115#ifdef LINKSPEED_DEBUG_ENABLED
6116 pr_info("Reporting actual MCS rate %d flags %x\n",
6117 sinfo->txrate.mcs,
6118 sinfo->txrate.flags );
6119#endif //LINKSPEED_DEBUG_ENABLED
6120 }
6121 }
6122 sinfo->filled |= STATION_INFO_TX_BITRATE;
6123
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006124 sinfo->tx_packets =
6125 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6126 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6127 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6128 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6129
6130 sinfo->tx_retries =
6131 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6132 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6133 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6134 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6135
6136 sinfo->tx_failed =
6137 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6138 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6139 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6140 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6141
6142 sinfo->filled |=
6143 STATION_INFO_TX_PACKETS |
6144 STATION_INFO_TX_RETRIES |
6145 STATION_INFO_TX_FAILED;
6146
6147 EXIT();
6148 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006149}
6150
6151static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6152 struct net_device *dev, bool mode, v_SINT_t timeout)
6153{
6154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6155 VOS_STATUS vos_status;
6156
Jeff Johnsone7245742012-09-05 17:12:55 -07006157 ENTER();
6158
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 if (NULL == pAdapter)
6160 {
6161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6162 return -ENODEV;
6163 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006164 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6165 {
6166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6167 "%s:LOGP in Progress. Ignore!!!", __func__);
6168 return -EAGAIN;
6169 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006170
6171 /**The get power cmd from the supplicant gets updated by the nl only
6172 *on successful execution of the function call
6173 *we are oppositely mapped w.r.t mode in the driver
6174 **/
6175 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6176
Jeff Johnsone7245742012-09-05 17:12:55 -07006177 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 if (VOS_STATUS_E_FAILURE == vos_status)
6179 {
6180 return -EINVAL;
6181 }
6182 return 0;
6183}
6184
6185
6186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6187static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6188 struct net_device *netdev,
6189 u8 key_index)
6190{
Jeff Johnsone7245742012-09-05 17:12:55 -07006191 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 return 0;
6193}
6194#endif //LINUX_VERSION_CODE
6195
6196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6197static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6198 struct net_device *dev,
6199 struct ieee80211_txq_params *params)
6200{
Jeff Johnsone7245742012-09-05 17:12:55 -07006201 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 return 0;
6203}
6204#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6205static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
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#endif //LINUX_VERSION_CODE
6212
6213static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6214 struct net_device *dev, u8 *mac)
6215{
6216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006217 VOS_STATUS vos_status;
6218 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006219
Jeff Johnsone7245742012-09-05 17:12:55 -07006220 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6222 {
6223 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6224 return -EINVAL;
6225 }
6226
6227 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6228 {
6229 hddLog( LOGE,
6230 "%s: Wlan Load/Unload is in progress", __func__);
6231 return -EBUSY;
6232 }
6233
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006234 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6235 {
6236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6237 "%s:LOGP in Progress. Ignore!!!", __func__);
6238 return -EAGAIN;
6239 }
6240
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6242#ifdef WLAN_FEATURE_P2P
6243 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6244#endif
6245 )
6246 {
6247 if( NULL == mac )
6248 {
6249 v_U16_t i;
6250 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6251 {
6252 if(pAdapter->aStaInfo[i].isUsed)
6253 {
6254 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6255 hddLog(VOS_TRACE_LEVEL_INFO,
6256 "%s: Delete STA with MAC::"
6257 "%02x:%02x:%02x:%02x:%02x:%02x",
6258 __func__,
6259 macAddr[0], macAddr[1], macAddr[2],
6260 macAddr[3], macAddr[4], macAddr[5]);
6261 hdd_softap_sta_deauth(pAdapter, macAddr);
6262 }
6263 }
6264 }
6265 else
6266 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006267
6268 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6269 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6270 {
6271 hddLog(VOS_TRACE_LEVEL_INFO,
6272 "%s: Skip this DEL STA as this is not used::"
6273 "%02x:%02x:%02x:%02x:%02x:%02x",
6274 __func__,
6275 mac[0], mac[1], mac[2],
6276 mac[3], mac[4], mac[5]);
6277 return -ENOENT;
6278 }
6279
6280 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6281 {
6282 hddLog(VOS_TRACE_LEVEL_INFO,
6283 "%s: Skip this DEL STA as deauth is in progress::"
6284 "%02x:%02x:%02x:%02x:%02x:%02x",
6285 __func__,
6286 mac[0], mac[1], mac[2],
6287 mac[3], mac[4], mac[5]);
6288 return -ENOENT;
6289 }
6290
6291 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6292
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 hddLog(VOS_TRACE_LEVEL_INFO,
6294 "%s: Delete STA with MAC::"
6295 "%02x:%02x:%02x:%02x:%02x:%02x",
6296 __func__,
6297 mac[0], mac[1], mac[2],
6298 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006299
6300 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6301 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6302 {
6303 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6304 hddLog(VOS_TRACE_LEVEL_INFO,
6305 "%s: STA removal failed for ::"
6306 "%02x:%02x:%02x:%02x:%02x:%02x",
6307 __func__,
6308 mac[0], mac[1], mac[2],
6309 mac[3], mac[4], mac[5]);
6310 return -ENOENT;
6311 }
6312
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 }
6314 }
6315
6316 EXIT();
6317
6318 return 0;
6319}
6320
6321static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6322 struct net_device *dev, u8 *mac, struct station_parameters *params)
6323{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006324#ifdef FEATURE_WLAN_TDLS
6325 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6326 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6327 u32 mask, set;
6328 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006329 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006330
6331 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6332 {
6333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6334 "Invalid arguments");
6335 return -EINVAL;
6336 }
6337
6338 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6339 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6340 {
6341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6342 "TDLS Disabled in INI OR not enabled in FW.\
6343 Cannot process TDLS commands \n");
6344 return -ENOTSUPP;
6345 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006346 /* first to check if we reached to maximum supported TDLS peer.
6347 TODO: for now, return -EPERM looks working fine,
6348 but need to check if any other errno fit into this category.*/
6349 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6350 {
6351 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6352 "%s: TDLS Max peer already connected. Request declined. \n",
6353 __func__);
6354 return -EPERM;
6355 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006356
6357 mask = params->sta_flags_mask;
6358
6359 set = params->sta_flags_set;
6360
6361
Lee Hoonkic1262f22013-01-24 21:59:00 -08006362 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6363 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006364
6365 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6366 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6368 "Add TDLS peer");
6369
6370
6371 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6372 pAdapter->sessionId, mac);
6373
6374 if (VOS_STATUS_SUCCESS != status) {
6375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6376 "%s: sme_AddTdlsPeerSta failed!", __func__);
6377 }
6378 }
6379 }
6380#endif
6381
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 return 0;
6383}
6384
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006385
6386#ifdef FEATURE_WLAN_LFR
6387static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006388 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006389{
6390#define MAX_PMKSAIDS_IN_CACHE 8
6391 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006392 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006393 tANI_U32 j=0;
6394 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6395 tHalHandle halHandle;
6396 eHalStatus result;
6397 tANI_U8 BSSIDMatched = 0;
6398
Jeff Johnsone7245742012-09-05 17:12:55 -07006399 ENTER();
6400
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006401 // Validate pAdapter
6402 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6403 {
6404 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6405 return -EINVAL;
6406 }
6407
6408 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6409 {
6410 hddLog( LOGE,
6411 "%s: Wlan Load/Unload is in progress", __func__);
6412 return -EBUSY;
6413 }
6414
6415 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6416 {
6417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6418 "%s:LOGP in Progress. Ignore!!!", __func__);
6419 return -EAGAIN;
6420 }
6421
6422 // Retrieve halHandle
6423 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6424
6425 for (j = 0; j < i; j++)
6426 {
6427 if(vos_mem_compare(PMKIDCache[j].BSSID,
6428 pmksa->bssid, WNI_CFG_BSSID_LEN))
6429 {
6430 /* BSSID matched previous entry. Overwrite it. */
6431 BSSIDMatched = 1;
6432 vos_mem_copy(PMKIDCache[j].BSSID,
6433 pmksa->bssid, WNI_CFG_BSSID_LEN);
6434 vos_mem_copy(PMKIDCache[j].PMKID,
6435 pmksa->pmkid,
6436 CSR_RSN_PMKID_SIZE);
6437 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006438 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006439 dump_bssid(pmksa->bssid);
6440 dump_pmkid(halHandle, pmksa->pmkid);
6441 break;
6442 }
6443 }
6444
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006445 /* Check we compared all entries,if then take the first slot now */
6446 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6447
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006448 if (!BSSIDMatched)
6449 {
6450 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6451 vos_mem_copy(PMKIDCache[i].BSSID,
6452 pmksa->bssid, ETHER_ADDR_LEN);
6453 vos_mem_copy(PMKIDCache[i].PMKID,
6454 pmksa->pmkid,
6455 CSR_RSN_PMKID_SIZE);
6456 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006457 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006458 dump_bssid(pmksa->bssid);
6459 dump_pmkid(halHandle, pmksa->pmkid);
6460 // Increment the HDD Local Cache index
6461 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6462 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6463 }
6464
6465
6466 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6467 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006468 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006469 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006470 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006471 // Finally set the PMKSA ID Cache in CSR
6472 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6473 PMKIDCache,
6474 i );
6475 return 0;
6476}
6477
6478
6479static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006480 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006481{
Jeff Johnsone7245742012-09-05 17:12:55 -07006482 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006483 // TODO: Implement this later.
6484 return 0;
6485}
6486
6487static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6488{
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#endif
6494
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006495#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6496static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6497 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6498{
6499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6500 hdd_station_ctx_t *pHddStaCtx;
6501
6502 if (NULL == pAdapter)
6503 {
6504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6505 return -ENODEV;
6506 }
6507
6508 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6509
6510 // Added for debug on reception of Re-assoc Req.
6511 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6512 {
6513 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6514 ftie->ie_len);
6515 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6516 }
6517
6518#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6519 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6520 ftie->ie_len);
6521#endif
6522
6523 // Pass the received FT IEs to SME
6524 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6525 ftie->ie_len);
6526 return 0;
6527}
6528#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006529
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006530#ifdef FEATURE_WLAN_TDLS
6531static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6532 u8 *peer, u8 action_code, u8 dialog_token,
6533 u16 status_code, const u8 *buf, size_t len)
6534{
6535
6536 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6537 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006538 u8 peerMac[6];
6539 VOS_STATUS status;
Hoonki Leea34dd892013-02-05 22:56:02 -08006540 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006541
6542 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6543 {
6544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6545 "Invalid arguments");
6546 return -EINVAL;
6547 }
6548
6549 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6550 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6551 {
6552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6553 "TDLS Disabled in INI OR not enabled in FW.\
6554 Cannot process TDLS commands \n");
6555 return -ENOTSUPP;
6556 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006557
6558 if(SIR_MAC_TDLS_SETUP_REQ == action_code ||
6559 SIR_MAC_TDLS_SETUP_RSP == action_code )
6560 {
6561 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6562 {
6563 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6564 we return error code at 'add_station()'. Hence we have this
6565 check again in addtion to add_station().
6566 Anyway, there is no hard to double-check. */
6567 if(SIR_MAC_TDLS_SETUP_REQ == action_code)
6568 {
6569 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6570 "%s: TDLS Max peer already connected. Request declined. \n",
6571 __func__);
6572 return -EPERM;
6573 }
6574 else
6575 {
6576 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6577 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6578 "%s: TDLS Max peer already connected send response status %d \n",
6579 __func__,status_code);
6580 }
6581 }
6582 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006583 vos_mem_copy( peerMac, peer, 6);
6584
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006585#ifdef WLAN_FEATURE_TDLS_DEBUG
6586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6587 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6588 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6589 action_code, dialog_token, status_code, len);
6590#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006591
Hoonki Leea34dd892013-02-05 22:56:02 -08006592 /*Except teardown responder will not be used so just make 0*/
6593 responder = 0;
6594 if(SIR_MAC_TDLS_TEARDOWN == action_code)
6595 {
6596 responder = wlan_hdd_tdls_get_responder(peerMac);
6597 if(-1 == responder)
6598 {
6599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6600 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6601 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6602 dialog_token, status_code, len);
6603 return -EPERM;
6604 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006605 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006606
6607 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006608 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006609
6610 if (VOS_STATUS_SUCCESS != status) {
6611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6612 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6613 }
6614
Hoonki Leea34dd892013-02-05 22:56:02 -08006615 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6616 {
6617 wlan_hdd_tdls_set_responder(peerMac, TRUE);
6618 }
6619 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6620 {
6621 wlan_hdd_tdls_set_responder(peerMac, FALSE);
6622 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006623
6624 return 0;
6625}
6626
6627static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6628 u8 *peer, enum nl80211_tdls_operation oper)
6629{
6630 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6631 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006632#ifdef WLAN_FEATURE_TDLS_DEBUG
6633 const char *tdls_oper_str[]= {
6634 "NL80211_TDLS_DISCOVERY_REQ",
6635 "NL80211_TDLS_SETUP",
6636 "NL80211_TDLS_TEARDOWN",
6637 "NL80211_TDLS_ENABLE_LINK",
6638 "NL80211_TDLS_DISABLE_LINK",
6639 "NL80211_TDLS_UNKONW_OPER"};
6640#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006641
6642 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6643 {
6644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6645 "Invalid arguments");
6646 return -EINVAL;
6647 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006648
6649#ifdef WLAN_FEATURE_TDLS_DEBUG
6650 if((int)oper > 4)
6651 oper = 5;
6652
6653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6654 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6655 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6656 tdls_oper_str[(int)oper]);
6657#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006658
6659 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006660 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006661 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006663 "TDLS Disabled in INI OR not enabled in FW.\
6664 Cannot process TDLS commands \n");
6665 return -ENOTSUPP;
6666 }
6667
6668 switch (oper) {
6669 case NL80211_TDLS_ENABLE_LINK:
6670 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006671 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Hoonki Lee387663d2013-02-05 18:08:43 -08006672 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006673 VOS_STATUS status;
6674
6675 if (peer) {
Hoonki Lee387663d2013-02-05 18:08:43 -08006676 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006677
6678 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006679 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006680 __func__, peer[0], peer[1],
6681 peer[2], peer[3],
6682 peer[4], peer[5] );
6683
Hoonki Lee387663d2013-02-05 18:08:43 -08006684 if ( NULL == pTdlsPeer ) {
6685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6686 __func__, peer[0], peer[1],
6687 peer[2], peer[3],
6688 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006689 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006690 }
6691
Hoonki Lee387663d2013-02-05 18:08:43 -08006692 status = WLANTL_ChangeSTAState( pVosContext, pTdlsPeer->staId,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006693 WLANTL_STA_AUTHENTICATED );
6694
Hoonki Leef63df0d2013-01-16 19:29:14 -08006695 //This can fail only if the staId is not registered yet with TL
6696 //return -EINVAL in such case.
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006697 if (0 != status) {
6698 hddLog(VOS_TRACE_LEVEL_ERROR,
6699 "%s: WLANTL_ChangeSTAState failed, returned %d",
6700 __func__, status);
Hoonki Leef63df0d2013-01-16 19:29:14 -08006701 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006702 }
Hoonki Leef63df0d2013-01-16 19:29:14 -08006703
Hoonki Lee387663d2013-02-05 18:08:43 -08006704 wlan_hdd_tdls_set_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Chilam NG571c65a2013-01-19 12:27:36 +05306705
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006706 } else {
6707 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6708 }
6709 }
6710 break;
6711 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006712 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006713 if(NULL != wlan_hdd_tdls_find_peer(peer))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006714 {
6715 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6716 pAdapter->sessionId, peer );
6717 }
6718 else
6719 {
6720 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6721 "%s: TDLS Peer Station doesn't exist \n",__func__);
6722 }
6723 return 0;
6724 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006725 case NL80211_TDLS_TEARDOWN:
6726 case NL80211_TDLS_SETUP:
6727 case NL80211_TDLS_DISCOVERY_REQ:
6728 /* We don't support in-driver setup/teardown/discovery */
6729 return -ENOTSUPP;
6730 default:
6731 return -ENOTSUPP;
6732 }
6733 return 0;
6734}
Chilam NG571c65a2013-01-19 12:27:36 +05306735
6736int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6737 struct net_device *dev, u8 *peer)
6738{
6739 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6740 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6741
6742 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6743 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6744}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006745#endif
6746
Jeff Johnson295189b2012-06-20 16:38:30 -07006747/* cfg80211_ops */
6748static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6749{
6750 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6751 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6752 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6753 .change_station = wlan_hdd_change_station,
6754#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6755 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6756 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6757 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006758#else
6759 .start_ap = wlan_hdd_cfg80211_start_ap,
6760 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6761 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006762#endif
6763 .change_bss = wlan_hdd_cfg80211_change_bss,
6764 .add_key = wlan_hdd_cfg80211_add_key,
6765 .get_key = wlan_hdd_cfg80211_get_key,
6766 .del_key = wlan_hdd_cfg80211_del_key,
6767 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006768#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006770#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 .scan = wlan_hdd_cfg80211_scan,
6772 .connect = wlan_hdd_cfg80211_connect,
6773 .disconnect = wlan_hdd_cfg80211_disconnect,
6774 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6775 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6776 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6777 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6778 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6779#ifdef WLAN_FEATURE_P2P
6780 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6781 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6782 .mgmt_tx = wlan_hdd_action,
6783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6784 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6785 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6786 .set_txq_params = wlan_hdd_set_txq_params,
6787#endif
6788#endif
6789 .get_station = wlan_hdd_cfg80211_get_station,
6790 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6791 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006792 .add_station = wlan_hdd_cfg80211_add_station,
6793#ifdef FEATURE_WLAN_LFR
6794 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6795 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6796 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6797#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006798#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6799 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6800#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006801#ifdef FEATURE_WLAN_TDLS
6802 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6803 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6804#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006805};
6806
6807#endif // CONFIG_CFG80211