blob: cfe9bedc339d2ea0d64a79b2a95f7d536ea0c9a7 [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
Jeff Johnson295189b2012-06-20 16:38:30 -070074
75#include <linux/version.h>
76#include <linux/module.h>
77#include <linux/kernel.h>
78#include <linux/init.h>
79#include <linux/wireless.h>
80#include <wlan_hdd_includes.h>
81#include <net/arp.h>
82#include <net/cfg80211.h>
83#include <linux/wireless.h>
84#include <wlan_hdd_wowl.h>
85#include <aniGlobal.h>
86#include "ccmApi.h"
87#include "sirParams.h"
88#include "dot11f.h"
89#include "wlan_hdd_assoc.h"
90#include "wlan_hdd_wext.h"
91#include "sme_Api.h"
92#include "wlan_hdd_p2p.h"
93#include "wlan_hdd_cfg80211.h"
94#include "wlan_hdd_hostapd.h"
95#include "sapInternal.h"
96#include "wlan_hdd_softap_tx_rx.h"
97#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053098#include "wlan_hdd_assoc.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099#ifdef WLAN_BTAMP_FEATURE
100#include "bap_hdd_misc.h"
101#endif
102#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800103#ifdef FEATURE_WLAN_TDLS
104#include "wlan_hdd_tdls.h"
105#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +0530106#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define g_mode_rates_size (12)
109#define a_mode_rates_size (8)
110#define FREQ_BASE_80211G (2407)
111#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700112#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
114 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
115
116#define HDD2GHZCHAN(freq, chan, flag) { \
117 .band = IEEE80211_BAND_2GHZ, \
118 .center_freq = (freq), \
119 .hw_value = (chan),\
120 .flags = (flag), \
121 .max_antenna_gain = 0 ,\
122 .max_power = 30, \
123}
124
125#define HDD5GHZCHAN(freq, chan, flag) { \
126 .band = IEEE80211_BAND_5GHZ, \
127 .center_freq = (freq), \
128 .hw_value = (chan),\
129 .flags = (flag), \
130 .max_antenna_gain = 0 ,\
131 .max_power = 30, \
132}
133
134#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
135{\
136 .bitrate = rate, \
137 .hw_value = rate_id, \
138 .flags = flag, \
139}
140
Lee Hoonkic1262f22013-01-24 21:59:00 -0800141#ifndef WLAN_FEATURE_TDLS_DEBUG
142#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
143#else
144#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
145#endif
146
Jeff Johnson295189b2012-06-20 16:38:30 -0700147static const u32 hdd_cipher_suites[] =
148{
149 WLAN_CIPHER_SUITE_WEP40,
150 WLAN_CIPHER_SUITE_WEP104,
151 WLAN_CIPHER_SUITE_TKIP,
152#ifdef FEATURE_WLAN_CCX
153#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
154 WLAN_CIPHER_SUITE_KRK,
155 WLAN_CIPHER_SUITE_CCMP,
156#else
157 WLAN_CIPHER_SUITE_CCMP,
158#endif
159#ifdef FEATURE_WLAN_WAPI
160 WLAN_CIPHER_SUITE_SMS4,
161#endif
162};
163
164static inline int is_broadcast_ether_addr(const u8 *addr)
165{
166 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
167 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
168}
169
170static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
171{
172 HDD2GHZCHAN(2412, 1, 0) ,
173 HDD2GHZCHAN(2417, 2, 0) ,
174 HDD2GHZCHAN(2422, 3, 0) ,
175 HDD2GHZCHAN(2427, 4, 0) ,
176 HDD2GHZCHAN(2432, 5, 0) ,
177 HDD2GHZCHAN(2437, 6, 0) ,
178 HDD2GHZCHAN(2442, 7, 0) ,
179 HDD2GHZCHAN(2447, 8, 0) ,
180 HDD2GHZCHAN(2452, 9, 0) ,
181 HDD2GHZCHAN(2457, 10, 0) ,
182 HDD2GHZCHAN(2462, 11, 0) ,
183 HDD2GHZCHAN(2467, 12, 0) ,
184 HDD2GHZCHAN(2472, 13, 0) ,
185 HDD2GHZCHAN(2484, 14, 0) ,
186};
187
Jeff Johnson295189b2012-06-20 16:38:30 -0700188static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
189{
190 HDD2GHZCHAN(2412, 1, 0) ,
191 HDD2GHZCHAN(2437, 6, 0) ,
192 HDD2GHZCHAN(2462, 11, 0) ,
193};
Jeff Johnson295189b2012-06-20 16:38:30 -0700194
195static struct ieee80211_channel hdd_channels_5_GHZ[] =
196{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700197 HDD5GHZCHAN(4920, 240, 0) ,
198 HDD5GHZCHAN(4940, 244, 0) ,
199 HDD5GHZCHAN(4960, 248, 0) ,
200 HDD5GHZCHAN(4980, 252, 0) ,
201 HDD5GHZCHAN(5040, 208, 0) ,
202 HDD5GHZCHAN(5060, 212, 0) ,
203 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 HDD5GHZCHAN(5180, 36, 0) ,
205 HDD5GHZCHAN(5200, 40, 0) ,
206 HDD5GHZCHAN(5220, 44, 0) ,
207 HDD5GHZCHAN(5240, 48, 0) ,
208 HDD5GHZCHAN(5260, 52, 0) ,
209 HDD5GHZCHAN(5280, 56, 0) ,
210 HDD5GHZCHAN(5300, 60, 0) ,
211 HDD5GHZCHAN(5320, 64, 0) ,
212 HDD5GHZCHAN(5500,100, 0) ,
213 HDD5GHZCHAN(5520,104, 0) ,
214 HDD5GHZCHAN(5540,108, 0) ,
215 HDD5GHZCHAN(5560,112, 0) ,
216 HDD5GHZCHAN(5580,116, 0) ,
217 HDD5GHZCHAN(5600,120, 0) ,
218 HDD5GHZCHAN(5620,124, 0) ,
219 HDD5GHZCHAN(5640,128, 0) ,
220 HDD5GHZCHAN(5660,132, 0) ,
221 HDD5GHZCHAN(5680,136, 0) ,
222 HDD5GHZCHAN(5700,140, 0) ,
223 HDD5GHZCHAN(5745,149, 0) ,
224 HDD5GHZCHAN(5765,153, 0) ,
225 HDD5GHZCHAN(5785,157, 0) ,
226 HDD5GHZCHAN(5805,161, 0) ,
227 HDD5GHZCHAN(5825,165, 0) ,
228};
229
230static struct ieee80211_rate g_mode_rates[] =
231{
232 HDD_G_MODE_RATETAB(10, 0x1, 0),
233 HDD_G_MODE_RATETAB(20, 0x2, 0),
234 HDD_G_MODE_RATETAB(55, 0x4, 0),
235 HDD_G_MODE_RATETAB(110, 0x8, 0),
236 HDD_G_MODE_RATETAB(60, 0x10, 0),
237 HDD_G_MODE_RATETAB(90, 0x20, 0),
238 HDD_G_MODE_RATETAB(120, 0x40, 0),
239 HDD_G_MODE_RATETAB(180, 0x80, 0),
240 HDD_G_MODE_RATETAB(240, 0x100, 0),
241 HDD_G_MODE_RATETAB(360, 0x200, 0),
242 HDD_G_MODE_RATETAB(480, 0x400, 0),
243 HDD_G_MODE_RATETAB(540, 0x800, 0),
244};
245
246static struct ieee80211_rate a_mode_rates[] =
247{
248 HDD_G_MODE_RATETAB(60, 0x10, 0),
249 HDD_G_MODE_RATETAB(90, 0x20, 0),
250 HDD_G_MODE_RATETAB(120, 0x40, 0),
251 HDD_G_MODE_RATETAB(180, 0x80, 0),
252 HDD_G_MODE_RATETAB(240, 0x100, 0),
253 HDD_G_MODE_RATETAB(360, 0x200, 0),
254 HDD_G_MODE_RATETAB(480, 0x400, 0),
255 HDD_G_MODE_RATETAB(540, 0x800, 0),
256};
257
258static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
259{
260 .channels = hdd_channels_2_4_GHZ,
261 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
262 .band = IEEE80211_BAND_2GHZ,
263 .bitrates = g_mode_rates,
264 .n_bitrates = g_mode_rates_size,
265 .ht_cap.ht_supported = 1,
266 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
267 | IEEE80211_HT_CAP_GRN_FLD
268 | IEEE80211_HT_CAP_DSSSCCK40
269 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
270 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
271 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
272 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
273 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
274 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
275};
276
Jeff Johnson295189b2012-06-20 16:38:30 -0700277static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
278{
279 .channels = hdd_social_channels_2_4_GHZ,
280 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
281 .band = IEEE80211_BAND_2GHZ,
282 .bitrates = g_mode_rates,
283 .n_bitrates = g_mode_rates_size,
284 .ht_cap.ht_supported = 1,
285 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
286 | IEEE80211_HT_CAP_GRN_FLD
287 | IEEE80211_HT_CAP_DSSSCCK40
288 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
289 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
290 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
291 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
292 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
293 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
294};
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
297{
298 .channels = hdd_channels_5_GHZ,
299 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
300 .band = IEEE80211_BAND_5GHZ,
301 .bitrates = a_mode_rates,
302 .n_bitrates = a_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
308 | IEEE80211_HT_CAP_SGI_40
309 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
310 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
311 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
312 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
313 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
314 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
315};
316
317/* This structure contain information what kind of frame are expected in
318 TX/RX direction for each kind of interface */
319static const struct ieee80211_txrx_stypes
320wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
321 [NL80211_IFTYPE_STATION] = {
322 .tx = 0xffff,
323 .rx = BIT(SIR_MAC_MGMT_ACTION) |
324 BIT(SIR_MAC_MGMT_PROBE_REQ),
325 },
326 [NL80211_IFTYPE_AP] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
329 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
330 BIT(SIR_MAC_MGMT_PROBE_REQ) |
331 BIT(SIR_MAC_MGMT_DISASSOC) |
332 BIT(SIR_MAC_MGMT_AUTH) |
333 BIT(SIR_MAC_MGMT_DEAUTH) |
334 BIT(SIR_MAC_MGMT_ACTION),
335 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 [NL80211_IFTYPE_P2P_CLIENT] = {
337 .tx = 0xffff,
338 .rx = BIT(SIR_MAC_MGMT_ACTION) |
339 BIT(SIR_MAC_MGMT_PROBE_REQ),
340 },
341 [NL80211_IFTYPE_P2P_GO] = {
342 /* This is also same as for SoftAP */
343 .tx = 0xffff,
344 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
346 BIT(SIR_MAC_MGMT_PROBE_REQ) |
347 BIT(SIR_MAC_MGMT_DISASSOC) |
348 BIT(SIR_MAC_MGMT_AUTH) |
349 BIT(SIR_MAC_MGMT_DEAUTH) |
350 BIT(SIR_MAC_MGMT_ACTION),
351 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700352};
353
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800354#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800355static const struct ieee80211_iface_limit
356wlan_hdd_iface_limit[] = {
357 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800358 /* max = 3 ; Our driver create two interfaces during driver init
359 * wlan0 and p2p0 interfaces. p2p0 is considered as station
360 * interface until a group is formed. In JB architecture, once the
361 * group is formed, interface type of p2p0 is changed to P2P GO or
362 * Client.
363 * When supplicant remove the group, it first issue a set interface
364 * cmd to change the mode back to Station. In JB this works fine as
365 * we advertize two station type interface during driver init.
366 * Some vendors create separate interface for P2P GO/Client,
367 * after group formation(Third one). But while group remove
368 * supplicant first tries to change the mode(3rd interface) to STATION
369 * But as we advertized only two sta type interfaces nl80211 was
370 * returning error for the third one which was leading to failure in
371 * delete interface. Ideally while removing the group, supplicant
372 * should not try to change the 3rd interface mode to Station type.
373 * Till we get a fix in wpa_supplicant, we advertize max STA
374 * interface type to 3
375 */
376 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800377 .types = BIT(NL80211_IFTYPE_STATION),
378 },
379 {
380 .max = 1,
381 .types = BIT(NL80211_IFTYPE_AP),
382 },
383 {
384 .max = 1,
385 .types = BIT(NL80211_IFTYPE_P2P_GO) |
386 BIT(NL80211_IFTYPE_P2P_CLIENT),
387 },
388};
389
390/* By default, only single channel concurrency is allowed */
391static struct ieee80211_iface_combination
392wlan_hdd_iface_combination = {
393 .limits = wlan_hdd_iface_limit,
394 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /*
396 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
397 * and p2p0 interfaces during driver init
398 * Some vendors create separate interface for P2P operations.
399 * wlan0: STA interface
400 * p2p0: P2P Device interface, action frames goes
401 * through this interface.
402 * p2p-xx: P2P interface, After GO negotiation this interface is
403 * created for p2p operations(GO/CLIENT interface).
404 */
405 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
407 .beacon_int_infra_match = false,
408};
409#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800410
Jeff Johnson295189b2012-06-20 16:38:30 -0700411static struct cfg80211_ops wlan_hdd_cfg80211_ops;
412
413/* Data rate 100KBPS based on IE Index */
414struct index_data_rate_type
415{
416 v_U8_t beacon_rate_index;
417 v_U16_t supported_rate[4];
418};
419
420/* 11B, 11G Rate table include Basic rate and Extended rate
421 The IDX field is the rate index
422 The HI field is the rate when RSSI is strong or being ignored
423 (in this case we report actual rate)
424 The MID field is the rate when RSSI is moderate
425 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
426 The LO field is the rate when RSSI is low
427 (in this case we don't report rates, actual current rate used)
428 */
429static const struct
430{
431 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700432 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700433} supported_data_rate[] =
434{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700435/* IDX HI HM LM LO (RSSI-based index */
436 {2, { 10, 10, 10, 0}},
437 {4, { 20, 20, 10, 0}},
438 {11, { 55, 20, 10, 0}},
439 {12, { 60, 55, 20, 0}},
440 {18, { 90, 55, 20, 0}},
441 {22, {110, 55, 20, 0}},
442 {24, {120, 90, 60, 0}},
443 {36, {180, 120, 60, 0}},
444 {44, {220, 180, 60, 0}},
445 {48, {240, 180, 90, 0}},
446 {66, {330, 180, 90, 0}},
447 {72, {360, 240, 90, 0}},
448 {96, {480, 240, 120, 0}},
449 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700450};
451
452/* MCS Based rate table */
453static struct index_data_rate_type supported_mcs_rate[] =
454{
455/* MCS L20 L40 S20 S40 */
456 {0, {65, 135, 72, 150}},
457 {1, {130, 270, 144, 300}},
458 {2, {195, 405, 217, 450}},
459 {3, {260, 540, 289, 600}},
460 {4, {390, 810, 433, 900}},
461 {5, {520, 1080, 578, 1200}},
462 {6, {585, 1215, 650, 1350}},
463 {7, {650, 1350, 722, 1500}}
464};
465
466extern struct net_device_ops net_ops_struct;
467
468/*
469 * FUNCTION: wlan_hdd_cfg80211_init
470 * This function is called by hdd_wlan_startup()
471 * during initialization.
472 * This function is used to initialize and register wiphy structure.
473 */
474struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
475{
476 struct wiphy *wiphy;
477 ENTER();
478
479 /*
480 * Create wiphy device
481 */
482 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
483
484 if (!wiphy)
485 {
486 /* Print error and jump into err label and free the memory */
487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
488 return NULL;
489 }
490
491 return wiphy;
492}
493
494/*
495 * FUNCTION: wlan_hdd_cfg80211_update_band
496 * This function is called from the supplicant through a
497 * private ioctl to change the band value
498 */
499int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
500{
Jeff Johnsone7245742012-09-05 17:12:55 -0700501 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700502 switch(eBand)
503 {
504 case eCSR_BAND_24:
505 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
506 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
507 break;
508 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700509 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700510 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
511 break;
512 case eCSR_BAND_ALL:
513 default:
514 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
515 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
516 }
517 return 0;
518}
519/*
520 * FUNCTION: wlan_hdd_cfg80211_init
521 * This function is called by hdd_wlan_startup()
522 * during initialization.
523 * This function is used to initialize and register wiphy structure.
524 */
525int wlan_hdd_cfg80211_register(struct device *dev,
526 struct wiphy *wiphy,
527 hdd_config_t *pCfg
528 )
529{
Jeff Johnsone7245742012-09-05 17:12:55 -0700530 ENTER();
531
Jeff Johnson295189b2012-06-20 16:38:30 -0700532 /* Now bind the underlying wlan device with wiphy */
533 set_wiphy_dev(wiphy, dev);
534
535 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
536
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700537 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700538
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700540 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
541 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
542 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700543 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700544#endif
James Zmuda77fb5ae2013-01-29 08:00:17 -0800545#ifdef FEATURE_WLAN_LFR
546 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
547#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800548#ifdef FEATURE_WLAN_TDLS
549 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
550 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
551#endif
552
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700553 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
554 driver can still register regulatory callback and
555 it will get CRDA setting in wiphy->band[], but
556 driver need to determine what to do with both
557 regulatory settings */
558 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700559
Jeff Johnson295189b2012-06-20 16:38:30 -0700560 wiphy->max_scan_ssids = MAX_SCAN_SSID;
561
562 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
563
564 /* Supports STATION & AD-HOC modes right now */
565 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
566 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700567 | BIT(NL80211_IFTYPE_P2P_CLIENT)
568 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 | BIT(NL80211_IFTYPE_AP);
570
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800572 if( pCfg->enableMCC )
573 {
574 /* Currently, supports up to two channels */
575 wlan_hdd_iface_combination.num_different_channels = 2;
576
577 if( !pCfg->allowMCCGODiffBI )
578 wlan_hdd_iface_combination.beacon_int_infra_match = true;
579
580 }
581 wiphy->iface_combinations = &wlan_hdd_iface_combination;
582 wiphy->n_iface_combinations = 1;
583#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800584
Jeff Johnson295189b2012-06-20 16:38:30 -0700585 /* Before registering we need to update the ht capabilitied based
586 * on ini values*/
587 if( !pCfg->ShortGI20MhzEnable )
588 {
589 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
590 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
591 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
592 }
593
594 if( !pCfg->ShortGI40MhzEnable )
595 {
596 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
597 }
598
599 if( !pCfg->nChannelBondingMode5GHz )
600 {
601 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
602 }
603
604 /*Initialize band capability*/
605 switch(pCfg->nBandCapability)
606 {
607 case eCSR_BAND_24:
608 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
609 break;
610 case eCSR_BAND_5G:
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
613 break;
614 case eCSR_BAND_ALL:
615 default:
616 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
617 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
618 }
619 /*Initialise the supported cipher suite details*/
620 wiphy->cipher_suites = hdd_cipher_suites;
621 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
622
623 /*signal strength in mBm (100*dBm) */
624 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
625
626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700627 wiphy->max_remain_on_channel_duration = 1000;
628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700629
630 /* Register our wiphy dev with cfg80211 */
631 if (0 > wiphy_register(wiphy))
632 {
633 /* print eror */
634 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
635 return -EIO;
636 }
637
638 EXIT();
639 return 0;
640}
641
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700642/* In this function we will try to get default country code from crda.
643 If the gCrdaDefaultCountryCode is configured in ini file,
644 we will try to call user space crda to get the regulatory settings for
645 that country. We will timeout if we can't get it from crda.
646 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
647*/
648int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
649{
650 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
651 if (memcmp(pCfg->crdaDefaultCountryCode,
652 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
653 {
654 init_completion(&pHddCtx->driver_crda_req);
655 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
656 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
657 CRDA_WAIT_TIME);
658 }
659 return 0;
660}
661
Jeff Johnson295189b2012-06-20 16:38:30 -0700662/* In this function we will do all post VOS start initialization.
663 In this function we will register for all frame in which supplicant
664 is interested.
665*/
666void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
667{
Jeff Johnson295189b2012-06-20 16:38:30 -0700668 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
669 /* Register for all P2P action, public action etc frames */
670 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
671
Jeff Johnsone7245742012-09-05 17:12:55 -0700672 ENTER();
673
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 /* Right now we are registering these frame when driver is getting
675 initialized. Once we will move to 2.6.37 kernel, in which we have
676 frame register ops, we will move this code as a part of that */
677 /* GAS Initial Request */
678 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
679 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
680
681 /* GAS Initial Response */
682 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
683 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
684
685 /* GAS Comeback Request */
686 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
687 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
688
689 /* GAS Comeback Response */
690 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
691 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
692
693 /* P2P Public Action */
694 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
695 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
696 P2P_PUBLIC_ACTION_FRAME_SIZE );
697
698 /* P2P Action */
699 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
700 (v_U8_t*)P2P_ACTION_FRAME,
701 P2P_ACTION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700702}
703
704void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
705{
Jeff Johnson295189b2012-06-20 16:38:30 -0700706 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
707 /* Register for all P2P action, public action etc frames */
708 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
709
Jeff Johnsone7245742012-09-05 17:12:55 -0700710 ENTER();
711
Jeff Johnson295189b2012-06-20 16:38:30 -0700712 /* Right now we are registering these frame when driver is getting
713 initialized. Once we will move to 2.6.37 kernel, in which we have
714 frame register ops, we will move this code as a part of that */
715 /* GAS Initial Request */
716
717 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
718 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
719
720 /* GAS Initial Response */
721 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
722 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
723
724 /* GAS Comeback Request */
725 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
726 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
727
728 /* GAS Comeback Response */
729 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
730 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
731
732 /* P2P Public Action */
733 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
734 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
735 P2P_PUBLIC_ACTION_FRAME_SIZE );
736
737 /* P2P Action */
738 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
739 (v_U8_t*)P2P_ACTION_FRAME,
740 P2P_ACTION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700741}
742
743#ifdef FEATURE_WLAN_WAPI
744void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
745 const u8 *mac_addr, u8 *key , int key_Len)
746{
747 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
748 tCsrRoamSetKey setKey;
749 v_BOOL_t isConnected = TRUE;
750 int status = 0;
751 v_U32_t roamId= 0xFF;
752 tANI_U8 *pKeyPtr = NULL;
753 int n = 0;
754
755 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
756 __func__,pAdapter->device_mode);
757
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530758 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700759 setKey.keyId = key_index; // Store Key ID
760 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
761 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
762 setKey.paeRole = 0 ; // the PAE role
763 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
764 {
765 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
766 }
767 else
768 {
769 isConnected = hdd_connIsConnected(pHddStaCtx);
770 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
771 }
772 setKey.keyLength = key_Len;
773 pKeyPtr = setKey.Key;
774 memcpy( pKeyPtr, key, key_Len);
775
776 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
777 __func__, key_Len);
778 for (n = 0 ; n < key_Len; n++)
779 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
780 __func__,n,setKey.Key[n]);
781
782 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
783 if ( isConnected )
784 {
785 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
786 pAdapter->sessionId, &setKey, &roamId );
787 }
788 if ( status != 0 )
789 {
790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
791 "[%4d] sme_RoamSetKey returned ERROR status= %d",
792 __LINE__, status );
793 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
794 }
795}
796#endif /* FEATURE_WLAN_WAPI*/
797
798#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
799int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
800 beacon_data_t **ppBeacon,
801 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700802#else
803int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
804 beacon_data_t **ppBeacon,
805 struct cfg80211_beacon_data *params,
806 int dtim_period)
807#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700808{
809 int size;
810 beacon_data_t *beacon = NULL;
811 beacon_data_t *old = NULL;
812 int head_len,tail_len;
813
Jeff Johnsone7245742012-09-05 17:12:55 -0700814 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700815 if (params->head && !params->head_len)
816 return -EINVAL;
817
818 old = pAdapter->sessionCtx.ap.beacon;
819
820 if (!params->head && !old)
821 return -EINVAL;
822
823 if (params->tail && !params->tail_len)
824 return -EINVAL;
825
826#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
827 /* Kernel 3.0 is not updating dtim_period for set beacon */
828 if (!params->dtim_period)
829 return -EINVAL;
830#endif
831
832 if(params->head)
833 head_len = params->head_len;
834 else
835 head_len = old->head_len;
836
837 if(params->tail || !old)
838 tail_len = params->tail_len;
839 else
840 tail_len = old->tail_len;
841
842 size = sizeof(beacon_data_t) + head_len + tail_len;
843
844 beacon = kzalloc(size, GFP_KERNEL);
845
846 if( beacon == NULL )
847 return -ENOMEM;
848
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700849#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700850 if(params->dtim_period || !old )
851 beacon->dtim_period = params->dtim_period;
852 else
853 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700854#else
855 if(dtim_period || !old )
856 beacon->dtim_period = dtim_period;
857 else
858 beacon->dtim_period = old->dtim_period;
859#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700860
861 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
862 beacon->tail = beacon->head + head_len;
863 beacon->head_len = head_len;
864 beacon->tail_len = tail_len;
865
866 if(params->head) {
867 memcpy (beacon->head,params->head,beacon->head_len);
868 }
869 else {
870 if(old)
871 memcpy (beacon->head,old->head,beacon->head_len);
872 }
873
874 if(params->tail) {
875 memcpy (beacon->tail,params->tail,beacon->tail_len);
876 }
877 else {
878 if(old)
879 memcpy (beacon->tail,old->tail,beacon->tail_len);
880 }
881
882 *ppBeacon = beacon;
883
884 kfree(old);
885
886 return 0;
887
888}
Jeff Johnson295189b2012-06-20 16:38:30 -0700889
890v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
891{
892 int left = length;
893 v_U8_t *ptr = pIes;
894 v_U8_t elem_id,elem_len;
895
896 while(left >= 2)
897 {
898 elem_id = ptr[0];
899 elem_len = ptr[1];
900 left -= 2;
901 if(elem_len > left)
902 {
903 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700904 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700905 eid,elem_len,left);
906 return NULL;
907 }
908 if (elem_id == eid)
909 {
910 return ptr;
911 }
912
913 left -= elem_len;
914 ptr += (elem_len + 2);
915 }
916 return NULL;
917}
918
Jeff Johnson295189b2012-06-20 16:38:30 -0700919/* Check if rate is 11g rate or not */
920static int wlan_hdd_rate_is_11g(u8 rate)
921{
922 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
923 u8 i;
924 for (i = 0; i < 8; i++)
925 {
926 if(rate == gRateArray[i])
927 return TRUE;
928 }
929 return FALSE;
930}
931
932/* Check for 11g rate and set proper 11g only mode */
933static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
934 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
935{
936 u8 i, num_rates = pIe[0];
937
938 pIe += 1;
939 for ( i = 0; i < num_rates; i++)
940 {
941 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
942 {
943 /* If rate set have 11g rate than change the mode to 11G */
944 *pSapHw_mode = eSAP_DOT11_MODE_11g;
945 if (pIe[i] & BASIC_RATE_MASK)
946 {
947 /* If we have 11g rate as basic rate, it means mode
948 is 11g only mode.
949 */
950 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
951 *pCheckRatesfor11g = FALSE;
952 }
953 }
954 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
955 {
956 *require_ht = TRUE;
957 }
958 }
959 return;
960}
961
962static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
963{
964 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
965 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
966 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
967 u8 checkRatesfor11g = TRUE;
968 u8 require_ht = FALSE;
969 u8 *pIe=NULL;
970
971 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
972
973 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
974 pBeacon->head_len, WLAN_EID_SUPP_RATES);
975 if (pIe != NULL)
976 {
977 pIe += 1;
978 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
979 &pConfig->SapHw_mode);
980 }
981
982 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
983 WLAN_EID_EXT_SUPP_RATES);
984 if (pIe != NULL)
985 {
986
987 pIe += 1;
988 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
989 &pConfig->SapHw_mode);
990 }
991
992 if( pConfig->channel > 14 )
993 {
994 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
995 }
996
997 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
998 WLAN_EID_HT_CAPABILITY);
999
1000 if(pIe)
1001 {
1002 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1003 if(require_ht)
1004 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1005 }
1006}
1007
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001008#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001009static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1010 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001011#else
1012static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1013 struct cfg80211_beacon_data *params)
1014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001015{
1016 v_U8_t *genie;
1017 v_U8_t total_ielen = 0, ielen = 0;
1018 v_U8_t *pIe = NULL;
1019 v_U8_t addIE[1] = {0};
1020 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -07001021 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001022
1023 genie = vos_mem_malloc(MAX_GENIE_LEN);
1024
1025 if(genie == NULL) {
1026
1027 return -ENOMEM;
1028 }
1029
1030 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1031
1032 if(pIe)
1033 {
1034 /*Copy the wps IE*/
1035 ielen = pIe[1] + 2;
1036 if( ielen <=MAX_GENIE_LEN)
1037 {
1038 vos_mem_copy(genie, pIe, ielen);
1039 }
1040 else
1041 {
1042 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001043 ret = -EINVAL;
1044 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001045 }
1046 total_ielen = ielen;
1047 }
1048
1049#ifdef WLAN_FEATURE_WFD
1050 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1051
1052 if(pIe)
1053 {
1054 ielen = pIe[1] + 2;
1055 if(total_ielen + ielen <= MAX_GENIE_LEN) {
1056 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
1057 }
1058 else {
1059 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001060 ret = -EINVAL;
1061 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001062 }
1063 total_ielen += ielen;
1064 }
1065#endif
1066
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1068
1069 if(pIe)
1070 {
1071 ielen = pIe[1] + 2;
1072 if(total_ielen + ielen <= MAX_GENIE_LEN)
1073 {
1074 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
1075 }
1076 else
1077 {
1078 hddLog( VOS_TRACE_LEVEL_ERROR,
1079 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001080 ret = -EINVAL;
1081 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 }
1083 total_ielen += ielen;
1084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001085
1086 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1087 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1088 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1089 {
1090 hddLog(LOGE,
1091 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001092 ret = -EINVAL;
1093 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001094 }
1095
1096 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1097 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1098 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1099 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1100 ==eHAL_STATUS_FAILURE)
1101 {
1102 hddLog(LOGE,
1103 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001104 ret = -EINVAL;
1105 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 }
1107
1108 // Added for ProResp IE
1109 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1110 {
1111 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1112 u8 probe_rsp_ie_len[3] = {0};
1113 u8 counter = 0;
1114 /* Check Probe Resp Length if it is greater then 255 then Store
1115 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1116 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1117 Store More then 255 bytes into One Variable.
1118 */
1119 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1120 {
1121 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1122 {
1123 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1124 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1125 }
1126 else
1127 {
1128 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1129 rem_probe_resp_ie_len = 0;
1130 }
1131 }
1132
1133 rem_probe_resp_ie_len = 0;
1134
1135 if (probe_rsp_ie_len[0] > 0)
1136 {
1137 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1138 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1139 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1140 probe_rsp_ie_len[0], NULL,
1141 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1142 {
1143 hddLog(LOGE,
1144 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001145 ret = -EINVAL;
1146 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001147 }
1148 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1149 }
1150
1151 if (probe_rsp_ie_len[1] > 0)
1152 {
1153 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1154 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1155 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1156 probe_rsp_ie_len[1], NULL,
1157 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1158 {
1159 hddLog(LOGE,
1160 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001161 ret = -EINVAL;
1162 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 }
1164 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1165 }
1166
1167 if (probe_rsp_ie_len[2] > 0)
1168 {
1169 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1170 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1171 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1172 probe_rsp_ie_len[2], NULL,
1173 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1174 {
1175 hddLog(LOGE,
1176 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001177 ret = -EINVAL;
1178 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 }
1180 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1181 }
1182
1183 if (probe_rsp_ie_len[1] == 0 )
1184 {
1185 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1186 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1187 eANI_BOOLEAN_FALSE) )
1188 {
1189 hddLog(LOGE,
1190 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1191 }
1192 }
1193
1194 if (probe_rsp_ie_len[2] == 0 )
1195 {
1196 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1197 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1198 eANI_BOOLEAN_FALSE) )
1199 {
1200 hddLog(LOGE,
1201 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1202 }
1203 }
1204
1205 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1206 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1207 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1208 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1209 == eHAL_STATUS_FAILURE)
1210 {
1211 hddLog(LOGE,
1212 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001213 ret = -EINVAL;
1214 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 }
1216 }
1217 else
1218 {
1219 // Reset WNI_CFG_PROBE_RSP Flags
1220 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1221
1222 hddLog(VOS_TRACE_LEVEL_INFO,
1223 "%s: No Probe Response IE received in set beacon",
1224 __func__);
1225 }
1226
1227 // Added for AssocResp IE
1228 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1229 {
1230 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1231 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1232 params->assocresp_ies_len, NULL,
1233 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1234 {
1235 hddLog(LOGE,
1236 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001237 ret = -EINVAL;
1238 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 }
1240
1241 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1242 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1243 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1244 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1245 == eHAL_STATUS_FAILURE)
1246 {
1247 hddLog(LOGE,
1248 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001249 ret = -EINVAL;
1250 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001251 }
1252 }
1253 else
1254 {
1255 hddLog(VOS_TRACE_LEVEL_INFO,
1256 "%s: No Assoc Response IE received in set beacon",
1257 __func__);
1258
1259 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1260 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1261 eANI_BOOLEAN_FALSE) )
1262 {
1263 hddLog(LOGE,
1264 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1265 }
1266 }
1267
Jeff Johnsone7245742012-09-05 17:12:55 -07001268done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001269 vos_mem_free(genie);
1270 return 0;
1271}
Jeff Johnson295189b2012-06-20 16:38:30 -07001272
1273/*
1274 * FUNCTION: wlan_hdd_validate_operation_channel
1275 * called by wlan_hdd_cfg80211_start_bss() and
1276 * wlan_hdd_cfg80211_set_channel()
1277 * This function validates whether given channel is part of valid
1278 * channel list.
1279 */
1280static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1281{
1282
1283 v_U32_t num_ch = 0;
1284 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1285 u32 indx = 0;
1286 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301287 v_U8_t fValidChannel = FALSE, count = 0;
1288 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07001289
1290 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1291
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301292 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001293 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301294 /* Validate the channel */
1295 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001296 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301297 if ( channel == rfChannels[count].channelNum )
1298 {
1299 fValidChannel = TRUE;
1300 break;
1301 }
1302 }
1303 if (fValidChannel != TRUE)
1304 {
1305 hddLog(VOS_TRACE_LEVEL_ERROR,
1306 "%s: Invalid Channel [%d]", __func__, channel);
1307 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 }
1309 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301310 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001311 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301312 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1313 valid_ch, &num_ch))
1314 {
1315 hddLog(VOS_TRACE_LEVEL_ERROR,
1316 "%s: failed to get valid channel list", __func__);
1317 return VOS_STATUS_E_FAILURE;
1318 }
1319 for (indx = 0; indx < num_ch; indx++)
1320 {
1321 if (channel == valid_ch[indx])
1322 {
1323 break;
1324 }
1325 }
1326
1327 if (indx >= num_ch)
1328 {
1329 hddLog(VOS_TRACE_LEVEL_ERROR,
1330 "%s: Invalid Channel [%d]", __func__, channel);
1331 return VOS_STATUS_E_FAILURE;
1332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001333 }
1334 return VOS_STATUS_SUCCESS;
1335
1336}
1337
Viral Modi3a32cc52013-02-08 11:14:52 -08001338/**
1339 * FUNCTION: wlan_hdd_cfg80211_set_channel
1340 * This function is used to set the channel number
1341 */
1342static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1343 struct ieee80211_channel *chan,
1344 enum nl80211_channel_type channel_type
1345 )
1346{
1347 v_U32_t num_ch = 0;
1348 u32 channel = 0;
1349 hdd_adapter_t *pAdapter = NULL;
1350 int freq = chan->center_freq; /* freq is in MHZ */
1351
1352 ENTER();
1353
1354 if( NULL == dev )
1355 {
1356 hddLog(VOS_TRACE_LEVEL_ERROR,
1357 "%s: Called with dev = NULL.\n", __func__);
1358 return -ENODEV;
1359 }
1360 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1361
1362 hddLog(VOS_TRACE_LEVEL_INFO,
1363 "%s: device_mode = %d freq = %d \n",__func__,
1364 pAdapter->device_mode, chan->center_freq);
1365 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1366 {
1367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1368 return -EAGAIN;
1369 }
1370
1371 /*
1372 * Do freq to chan conversion
1373 * TODO: for 11a
1374 */
1375
1376 channel = ieee80211_frequency_to_channel(freq);
1377
1378 /* Check freq range */
1379 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1380 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1381 {
1382 hddLog(VOS_TRACE_LEVEL_ERROR,
1383 "%s: Channel [%d] is outside valid range from %d to %d\n",
1384 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1385 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1386 return -EINVAL;
1387 }
1388
1389 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1390
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301391 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1392 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001393 {
1394 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1395 {
1396 hddLog(VOS_TRACE_LEVEL_ERROR,
1397 "%s: Invalid Channel [%d] \n", __func__, channel);
1398 return -EINVAL;
1399 }
1400 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1401 "%s: set channel to [%d] for device mode =%d",
1402 __func__, channel,pAdapter->device_mode);
1403 }
1404 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001405 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001406 )
1407 {
1408 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1409 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1410 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1411
1412 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1413 {
1414 /* Link is up then return cant set channel*/
1415 hddLog( VOS_TRACE_LEVEL_ERROR,
1416 "%s: IBSS Associated, can't set the channel\n", __func__);
1417 return -EINVAL;
1418 }
1419
1420 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1421 pHddStaCtx->conn_info.operationChannel = channel;
1422 pRoamProfile->ChannelInfo.ChannelList =
1423 &pHddStaCtx->conn_info.operationChannel;
1424 }
1425 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001426 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001427 )
1428 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301429 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1430 {
1431 if(VOS_STATUS_SUCCESS !=
1432 wlan_hdd_validate_operation_channel(pAdapter,channel))
1433 {
1434 hddLog(VOS_TRACE_LEVEL_ERROR,
1435 "%s: Invalid Channel [%d] \n", __func__, channel);
1436 return -EINVAL;
1437 }
1438 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1439 }
1440 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001441 {
1442 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1443
1444 /* If auto channel selection is configured as enable/ 1 then ignore
1445 channel set by supplicant
1446 */
1447 if ( cfg_param->apAutoChannelSelection )
1448 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301449 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1450 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001451 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1452 "%s: set channel to auto channel (0) for device mode =%d",
1453 __func__, pAdapter->device_mode);
1454 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301455 else
1456 {
1457 if(VOS_STATUS_SUCCESS !=
1458 wlan_hdd_validate_operation_channel(pAdapter,channel))
1459 {
1460 hddLog(VOS_TRACE_LEVEL_ERROR,
1461 "%s: Invalid Channel [%d] \n", __func__, channel);
1462 return -EINVAL;
1463 }
1464 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1465 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001466 }
1467 }
1468 else
1469 {
1470 hddLog(VOS_TRACE_LEVEL_FATAL,
1471 "%s: Invalid device mode failed to set valid channel", __func__);
1472 return -EINVAL;
1473 }
1474 EXIT();
1475 return 0;
1476}
1477
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301478/*
1479 * FUNCTION: wlan_hdd_select_cbmode
1480 * called by wlan_hdd_cfg80211_start_bss() and
1481 * This function selects the cbmode based on primary channel
1482 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001483VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301484{
1485 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001486 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1487 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1488
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301489 if(
1490#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001491 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1492 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301493#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001494 SapHw_mode != eSAP_DOT11_MODE_11n &&
1495 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301496 )
1497 {
1498 return VOS_STATUS_SUCCESS;
1499 }
1500
1501 if (!pConfigIni->nChannelBondingMode5GHz) {
1502 return VOS_STATUS_SUCCESS;
1503 }
1504
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001505 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301506 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1507
1508 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1509
1510#ifdef WLAN_FEATURE_11AC
1511
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001512 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1513 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301514 {
1515 if ( channel== 36 || channel == 52 || channel == 100 ||
1516 channel == 116 || channel == 149 )
1517 {
1518 smeConfig.csrConfig.channelBondingMode5GHz =
1519 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1520 }
1521 else if ( channel == 40 || channel == 56 || channel == 104 ||
1522 channel == 120 || channel == 153 )
1523 {
1524 smeConfig.csrConfig.channelBondingMode5GHz =
1525 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1526 }
1527 else if ( channel == 44 || channel == 60 || channel == 108 ||
1528 channel == 124 || channel == 157 )
1529 {
1530 smeConfig.csrConfig.channelBondingMode5GHz =
1531 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1532 }
1533 else if ( channel == 48 || channel == 64 || channel == 112 ||
1534 channel == 128 || channel == 161 )
1535 {
1536 smeConfig.csrConfig.channelBondingMode5GHz =
1537 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1538 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001539 else if ( channel == 165 )
1540 {
1541 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1542 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301543 }
1544#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001545 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1546 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301547 {
1548 if ( channel== 40 || channel == 48 || channel == 56 ||
1549 channel == 64 || channel == 104 || channel == 112 ||
1550 channel == 120 || channel == 128 || channel == 136 ||
1551 channel == 144 || channel == 153 || channel == 161 )
1552 {
1553 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1554 }
1555 else if ( channel== 36 || channel == 44 || channel == 52 ||
1556 channel == 60 || channel == 100 || channel == 108 ||
1557 channel == 116 || channel == 124 || channel == 132 ||
1558 channel == 140 || channel == 149 || channel == 157 )
1559 {
1560 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1561 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001562 else if ( channel == 165 )
1563 {
1564 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1565 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301566 }
1567 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1568
1569 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1570 return VOS_STATUS_SUCCESS;
1571}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001572
Jeff Johnson295189b2012-06-20 16:38:30 -07001573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1574static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1575 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001576#else
1577static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1578 struct cfg80211_beacon_data *params,
1579 const u8 *ssid, size_t ssid_len,
1580 enum nl80211_hidden_ssid hidden_ssid)
1581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001582{
1583 tsap_Config_t *pConfig;
1584 beacon_data_t *pBeacon = NULL;
1585 struct ieee80211_mgmt *pMgmt_frame;
1586 v_U8_t *pIe=NULL;
1587 v_U16_t capab_info;
1588 eCsrAuthType RSNAuthType;
1589 eCsrEncryptionType RSNEncryptType;
1590 eCsrEncryptionType mcRSNEncryptType;
1591 int status = VOS_STATUS_SUCCESS;
1592 tpWLAN_SAPEventCB pSapEventCallback;
1593 hdd_hostapd_state_t *pHostapdState;
1594 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1595 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301596 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001597 struct qc_mac_acl_entry *acl_entry = NULL;
1598 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001599 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001600
1601 ENTER();
1602
1603 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1604
1605 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1606
1607 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1608
1609 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1610
1611 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1612
1613 //channel is already set in the set_channel Call back
1614 //pConfig->channel = pCommitConfig->channel;
1615
1616 /*Protection parameter to enable or disable*/
1617 pConfig->protEnabled =
1618 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1619
1620 pConfig->dtim_period = pBeacon->dtim_period;
1621
1622 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1623 pConfig->dtim_period);
1624
1625
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001626 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001627 {
1628 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001630 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001632 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001633 pConfig->ieee80211d = 1;
1634 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1635 sme_setRegInfo(hHal, pConfig->countryCode);
1636 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001638 else
1639 {
1640 pConfig->ieee80211d = 0;
1641 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301642 /*
1643 * If auto channel is configured i.e. channel is 0,
1644 * so skip channel validation.
1645 */
1646 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1647 {
1648 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1652 return -EINVAL;
1653 }
1654 }
1655 else
1656 {
1657 if(1 != pHddCtx->is_dynamic_channel_range_set)
1658 {
1659 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1660 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1661 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1662 }
1663 pHddCtx->is_dynamic_channel_range_set = 0;
1664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001666 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 {
1668 pConfig->ieee80211d = 0;
1669 }
1670 pConfig->authType = eSAP_AUTO_SWITCH;
1671
1672 capab_info = pMgmt_frame->u.beacon.capab_info;
1673
1674 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1675 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1676
1677 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1678
1679 /*Set wps station to configured*/
1680 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1681
1682 if(pIe)
1683 {
1684 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1685 {
1686 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1687 return -EINVAL;
1688 }
1689 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1690 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001691 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 /* Check 15 bit of WPS IE as it contain information for wps state
1693 * WPS state
1694 */
1695 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1696 {
1697 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1698 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1699 {
1700 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1701 }
1702 }
1703 }
1704 else
1705 {
1706 pConfig->wps_state = SAP_WPS_DISABLED;
1707 }
1708 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1709
1710 pConfig->RSNWPAReqIELength = 0;
1711 pConfig->pRSNWPAReqIE = NULL;
1712 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1713 WLAN_EID_RSN);
1714 if(pIe && pIe[1])
1715 {
1716 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1717 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1718 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1719 /* The actual processing may eventually be more extensive than
1720 * this. Right now, just consume any PMKIDs that are sent in
1721 * by the app.
1722 * */
1723 status = hdd_softap_unpackIE(
1724 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1725 &RSNEncryptType,
1726 &mcRSNEncryptType,
1727 &RSNAuthType,
1728 pConfig->pRSNWPAReqIE[1]+2,
1729 pConfig->pRSNWPAReqIE );
1730
1731 if( VOS_STATUS_SUCCESS == status )
1732 {
1733 /* Now copy over all the security attributes you have
1734 * parsed out
1735 * */
1736 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1737 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1738 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1739 = RSNEncryptType;
1740 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1741 "EncryptionType = %d mcEncryptionType = %d\n"),
1742 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1743 }
1744 }
1745
1746 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1747 pBeacon->tail, pBeacon->tail_len);
1748
1749 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1750 {
1751 if (pConfig->pRSNWPAReqIE)
1752 {
1753 /*Mixed mode WPA/WPA2*/
1754 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1755 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1756 }
1757 else
1758 {
1759 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1760 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1761 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1762 status = hdd_softap_unpackIE(
1763 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1764 &RSNEncryptType,
1765 &mcRSNEncryptType,
1766 &RSNAuthType,
1767 pConfig->pRSNWPAReqIE[1]+2,
1768 pConfig->pRSNWPAReqIE );
1769
1770 if( VOS_STATUS_SUCCESS == status )
1771 {
1772 /* Now copy over all the security attributes you have
1773 * parsed out
1774 * */
1775 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1776 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1777 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1778 = RSNEncryptType;
1779 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1780 "EncryptionType = %d mcEncryptionType = %d\n"),
1781 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1782 }
1783 }
1784 }
1785
1786 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1787
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001788#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 if (params->ssid != NULL)
1790 {
1791 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1792 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1793 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1794 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1795 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001796#else
1797 if (ssid != NULL)
1798 {
1799 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1800 pConfig->SSIDinfo.ssid.length = ssid_len;
1801 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1802 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1803 }
1804#endif
1805
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 vos_mem_copy(pConfig->self_macaddr.bytes,
1807 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1808
1809 /* default value */
1810 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1811 pConfig->num_accept_mac = 0;
1812 pConfig->num_deny_mac = 0;
1813
1814 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1815 pBeacon->tail, pBeacon->tail_len);
1816
1817 /* pIe for black list is following form:
1818 type : 1 byte
1819 length : 1 byte
1820 OUI : 4 bytes
1821 acl type : 1 byte
1822 no of mac addr in black list: 1 byte
1823 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1824 */
1825 if ((pIe != NULL) && (pIe[1] != 0))
1826 {
1827 pConfig->SapMacaddr_acl = pIe[6];
1828 pConfig->num_deny_mac = pIe[7];
1829 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1830 pIe[6], pIe[7]);
1831 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1832 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1833 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1834 for (i = 0; i < pConfig->num_deny_mac; i++)
1835 {
1836 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1837 acl_entry++;
1838 }
1839 }
1840 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1841 pBeacon->tail, pBeacon->tail_len);
1842
1843 /* pIe for white list is following form:
1844 type : 1 byte
1845 length : 1 byte
1846 OUI : 4 bytes
1847 acl type : 1 byte
1848 no of mac addr in white list: 1 byte
1849 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1850 */
1851 if ((pIe != NULL) && (pIe[1] != 0))
1852 {
1853 pConfig->SapMacaddr_acl = pIe[6];
1854 pConfig->num_accept_mac = pIe[7];
1855 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1856 pIe[6], pIe[7]);
1857 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1858 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1859 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1860 for (i = 0; i < pConfig->num_accept_mac; i++)
1861 {
1862 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1863 acl_entry++;
1864 }
1865 }
1866 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1867
Jeff Johnsone7245742012-09-05 17:12:55 -07001868#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001869 /* Overwrite the hostapd setting for HW mode only for 11ac.
1870 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1871 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1872 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1873 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1874 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1875 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1876 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001877 {
1878 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1879 }
1880#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301881
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001882 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1883 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001884 // ht_capab is not what the name conveys,this is used for protection bitmap
1885 pConfig->ht_capab =
1886 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1887
1888 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1889 {
1890 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1891 return -EINVAL;
1892 }
1893
1894 //Uapsd Enabled Bit
1895 pConfig->UapsdEnable =
1896 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1897 //Enable OBSS protection
1898 pConfig->obssProtEnabled =
1899 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1900
1901 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1902 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1903 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1904 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1905 (int)pConfig->channel);
1906 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1907 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1908 pConfig->authType);
1909 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1910 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1911 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1912 pConfig->protEnabled, pConfig->obssProtEnabled);
1913
1914 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1915 {
1916 //Bss already started. just return.
1917 //TODO Probably it should update some beacon params.
1918 hddLog( LOGE, "Bss Already started...Ignore the request");
1919 EXIT();
1920 return 0;
1921 }
1922
1923 pConfig->persona = pHostapdAdapter->device_mode;
1924
1925 pSapEventCallback = hdd_hostapd_SAPEventCB;
1926 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1927 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1928 {
1929 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1930 return -EINVAL;
1931 }
1932
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001933 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001934 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1935
1936 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1937
1938 if (!VOS_IS_STATUS_SUCCESS(status))
1939 {
1940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1941 ("ERROR: HDD vos wait for single_event failed!!\n"));
1942 VOS_ASSERT(0);
1943 }
1944
1945 //Succesfully started Bss update the state bit.
1946 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1947
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001948#ifdef WLAN_FEATURE_P2P_DEBUG
1949 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1950 {
1951 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1952 {
1953 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1954 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001955 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001956 }
1957 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1958 {
1959 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1960 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001961 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001962 }
1963 }
1964#endif
1965
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 pHostapdState->bCommit = TRUE;
1967 EXIT();
1968
1969 return 0;
1970}
1971
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001972#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001973static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1974 struct net_device *dev,
1975 struct beacon_parameters *params)
1976{
1977 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1978 int status=VOS_STATUS_SUCCESS;
1979
1980 ENTER();
1981
1982 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1983
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001984 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1985 {
1986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1987 "%s:LOGP in Progress. Ignore!!!", __func__);
1988 return -EAGAIN;
1989 }
1990
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07001992 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07001993 )
1994 {
1995 beacon_data_t *old,*new;
1996
1997 old = pAdapter->sessionCtx.ap.beacon;
1998
1999 if (old)
2000 return -EALREADY;
2001
2002 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2003
2004 if(status != VOS_STATUS_SUCCESS)
2005 {
2006 hddLog(VOS_TRACE_LEVEL_FATAL,
2007 "%s:Error!!! Allocating the new beacon\n",__func__);
2008 return -EINVAL;
2009 }
2010
2011 pAdapter->sessionCtx.ap.beacon = new;
2012
2013 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2014 }
2015
2016 EXIT();
2017 return status;
2018}
2019
2020static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
2021 struct net_device *dev,
2022 struct beacon_parameters *params)
2023{
2024 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2025 int status=VOS_STATUS_SUCCESS;
2026
2027 ENTER();
2028
2029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2030 __func__,pAdapter->device_mode);
2031
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002032 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2033 {
2034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2035 "%s:LOGP in Progress. Ignore!!!", __func__);
2036 return -EAGAIN;
2037 }
2038
Jeff Johnson295189b2012-06-20 16:38:30 -07002039 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002040 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 )
2042 {
2043 beacon_data_t *old,*new;
2044
2045 old = pAdapter->sessionCtx.ap.beacon;
2046
2047 if (!old)
2048 return -ENOENT;
2049
2050 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2051
2052 if(status != VOS_STATUS_SUCCESS) {
2053 hddLog(VOS_TRACE_LEVEL_FATAL,
2054 "%s: Error!!! Allocating the new beacon\n",__func__);
2055 return -EINVAL;
2056 }
2057
2058 pAdapter->sessionCtx.ap.beacon = new;
2059
2060 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2061 }
2062
2063 EXIT();
2064 return status;
2065}
2066
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002067#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2068
2069#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002070static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2071 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002072#else
2073static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2074 struct net_device *dev)
2075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002076{
2077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002078 hdd_context_t *pHddCtx = NULL;
2079 hdd_scaninfo_t *pScanInfo = NULL;
2080 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 VOS_STATUS status = 0;
2082
2083 ENTER();
2084
2085 if (NULL == pAdapter)
2086 {
2087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002088 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002089 return -ENODEV;
2090 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002091 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2092 {
2093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2094 "%s:LOGP in Progress. Ignore!!!", __func__);
2095 return -EAGAIN;
2096 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002097
2098 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2099 if (NULL == pHddCtx)
2100 {
2101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002102 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002103 return -ENODEV;
2104 }
2105
2106 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2107 if (NULL == staAdapter)
2108 {
2109 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2110 if (NULL == staAdapter)
2111 {
2112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002113 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002114 return -ENODEV;
2115 }
2116 }
2117
2118 pScanInfo = &pHddCtx->scan_info;
2119
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2121 {
2122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2123 return -EAGAIN;
2124 }
2125
2126 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2127
2128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2129 __func__,pAdapter->device_mode);
2130
Jeff Johnsone7245742012-09-05 17:12:55 -07002131 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2132 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002133 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002134 hdd_abort_mac_scan(staAdapter->pHddCtx);
2135 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002136 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002137 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2138 if (!status)
2139 {
2140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002141 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002142 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002143 VOS_ASSERT(pScanInfo->mScanPending);
2144 return 0;
2145 }
2146 }
2147
Jeff Johnson295189b2012-06-20 16:38:30 -07002148 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002149 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 )
2151 {
2152 beacon_data_t *old;
2153
2154 old = pAdapter->sessionCtx.ap.beacon;
2155
2156 if (!old)
2157 return -ENOENT;
2158
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002160
2161 mutex_lock(&pHddCtx->sap_lock);
2162 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2163 {
2164 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2165 {
2166 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2167
2168 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2169
2170 if (!VOS_IS_STATUS_SUCCESS(status))
2171 {
2172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2173 ("ERROR: HDD vos wait for single_event failed!!\n"));
2174 VOS_ASSERT(0);
2175 }
2176 }
2177 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2178 }
2179 mutex_unlock(&pHddCtx->sap_lock);
2180
2181 if(status != VOS_STATUS_SUCCESS)
2182 {
2183 hddLog(VOS_TRACE_LEVEL_FATAL,
2184 "%s:Error!!! Stopping the BSS\n",__func__);
2185 return -EINVAL;
2186 }
2187
2188 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2189 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2190 ==eHAL_STATUS_FAILURE)
2191 {
2192 hddLog(LOGE,
2193 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2194 }
2195
2196 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2197 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2198 eANI_BOOLEAN_FALSE) )
2199 {
2200 hddLog(LOGE,
2201 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2202 }
2203
2204 // Reset WNI_CFG_PROBE_RSP Flags
2205 wlan_hdd_reset_prob_rspies(pAdapter);
2206
2207 pAdapter->sessionCtx.ap.beacon = NULL;
2208 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002209#ifdef WLAN_FEATURE_P2P_DEBUG
2210 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2211 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2212 {
2213 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2214 "GO got removed");
2215 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2216 }
2217#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 }
2219 EXIT();
2220 return status;
2221}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002222
2223#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2224
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302225static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2226 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002227 struct cfg80211_ap_settings *params)
2228{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302229 hdd_adapter_t *pAdapter;
2230 hdd_context_t *pHddCtx;
2231 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002232
2233 ENTER();
2234
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302235 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002236 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2238 "%s: Device is Null", __func__);
2239 return -ENODEV;
2240 }
2241
2242 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2243 if (NULL == pAdapter)
2244 {
2245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2246 "%s: HDD adapter is Null", __func__);
2247 return -ENODEV;
2248 }
2249
2250 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2251 {
2252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2253 "%s: HDD adapter magic is invalid", __func__);
2254 return -ENODEV;
2255 }
2256
2257 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2258 if (NULL == pHddCtx)
2259 {
2260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2261 "%s: HDD context is Null", __func__);
2262 return -ENODEV;
2263 }
2264
2265 if (pHddCtx->isLogpInProgress)
2266 {
2267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2268 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002269 return -EAGAIN;
2270 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302271
2272 if (pHddCtx->isLoadUnloadInProgress)
2273 {
2274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2275 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2276 return -EAGAIN;
2277 }
2278
2279 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2280 __func__, pAdapter->device_mode);
2281
2282 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002283 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002284 )
2285 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302286 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002287
2288 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302289
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002290 if (old)
2291 return -EALREADY;
2292
2293 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2294
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302295 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002296 {
2297 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302298 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002299 return -EINVAL;
2300 }
2301 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2303 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2304#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002305 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2306 params->ssid_len, params->hidden_ssid);
2307 }
2308
2309 EXIT();
2310 return status;
2311}
2312
2313
2314static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2315 struct net_device *dev,
2316 struct cfg80211_beacon_data *params)
2317{
2318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2319 int status=VOS_STATUS_SUCCESS;
2320
2321 ENTER();
2322
2323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2324 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002325 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2326 {
2327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2328 return -EAGAIN;
2329 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002330
2331 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002332 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002333 )
2334 {
2335 beacon_data_t *old,*new;
2336
2337 old = pAdapter->sessionCtx.ap.beacon;
2338
2339 if (!old)
2340 return -ENOENT;
2341
2342 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2343
2344 if(status != VOS_STATUS_SUCCESS) {
2345 hddLog(VOS_TRACE_LEVEL_FATAL,
2346 "%s: Error!!! Allocating the new beacon\n",__func__);
2347 return -EINVAL;
2348 }
2349
2350 pAdapter->sessionCtx.ap.beacon = new;
2351
2352 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2353 }
2354
2355 EXIT();
2356 return status;
2357}
2358
2359#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2360
Jeff Johnson295189b2012-06-20 16:38:30 -07002361
2362static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2363 struct net_device *dev,
2364 struct bss_parameters *params)
2365{
2366 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2367
2368 ENTER();
2369
2370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2371 __func__,pAdapter->device_mode);
2372
2373 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 )
2376 {
2377 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2378 * want to update this parameter */
2379 if (-1 != params->ap_isolate)
2380 {
2381 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2382 }
2383 }
2384
2385 EXIT();
2386 return 0;
2387}
2388
2389/*
2390 * FUNCTION: wlan_hdd_cfg80211_change_iface
2391 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2392 */
2393int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2394 struct net_device *ndev,
2395 enum nl80211_iftype type,
2396 u32 *flags,
2397 struct vif_params *params
2398 )
2399{
2400 struct wireless_dev *wdev;
2401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002403 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002404 tCsrRoamProfile *pRoamProfile = NULL;
2405 eCsrRoamBssType LastBSSType;
2406 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2407 eMib_dot11DesiredBssType connectedBssType;
2408 VOS_STATUS status;
2409
2410 ENTER();
2411
2412 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2413 {
2414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2415 return -EAGAIN;
2416 }
2417
2418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2419 __func__, pAdapter->device_mode);
2420
2421 wdev = ndev->ieee80211_ptr;
2422
2423#ifdef WLAN_BTAMP_FEATURE
2424 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2425 (NL80211_IFTYPE_ADHOC == type)||
2426 (NL80211_IFTYPE_AP == type)||
2427 (NL80211_IFTYPE_P2P_GO == type))
2428 {
2429 pHddCtx->isAmpAllowed = VOS_FALSE;
2430 // stop AMP traffic
2431 status = WLANBAP_StopAmp();
2432 if(VOS_STATUS_SUCCESS != status )
2433 {
2434 pHddCtx->isAmpAllowed = VOS_TRUE;
2435 hddLog(VOS_TRACE_LEVEL_FATAL,
2436 "%s: Failed to stop AMP", __func__);
2437 return -EINVAL;
2438 }
2439 }
2440#endif //WLAN_BTAMP_FEATURE
2441 /* Reset the current device mode bit mask*/
2442 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2443
2444 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002445 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002446 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 )
2448 {
2449 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2450 pRoamProfile = &pWextState->roamProfile;
2451 LastBSSType = pRoamProfile->BSSType;
2452
2453 switch (type)
2454 {
2455 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002457 hddLog(VOS_TRACE_LEVEL_INFO,
2458 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2459 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002460#ifdef WLAN_FEATURE_11AC
2461 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2462 {
2463 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2464 }
2465#endif
2466 pRoamProfile->phyMode =
2467 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002468 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002469 //Check for sub-string p2p to confirm its a p2p interface
2470 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002471 {
2472 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2473 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2474 }
2475 else
2476 {
2477 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002478 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002480 break;
2481 case NL80211_IFTYPE_ADHOC:
2482 hddLog(VOS_TRACE_LEVEL_INFO,
2483 "%s: setting interface Type to ADHOC", __func__);
2484 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2485 pRoamProfile->phyMode =
2486 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2487 wdev->iftype = type;
2488 break;
2489
2490 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002491 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002492 {
2493 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2494 "%s: setting interface Type to %s", __func__,
2495 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2496
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002497 //Cancel any remain on channel for GO mode
2498 if (NL80211_IFTYPE_P2P_GO == type)
2499 {
2500 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2501 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002502 if (NL80211_IFTYPE_AP == type)
2503 {
2504 /* As Loading WLAN Driver one interface being created for p2p device
2505 * address. This will take one HW STA and the max number of clients
2506 * that can connect to softAP will be reduced by one. so while changing
2507 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2508 * interface as it is not required in SoftAP mode.
2509 */
2510
2511 // Get P2P Adapter
2512 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2513
2514 if (pP2pAdapter)
2515 {
2516 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2517 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2518 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2519 }
2520 }
2521
Jeff Johnson295189b2012-06-20 16:38:30 -07002522 //De-init the adapter.
2523 hdd_stop_adapter( pHddCtx, pAdapter );
2524 hdd_deinit_adapter( pHddCtx, pAdapter );
2525 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002526 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2527 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002528
2529 //Disable BMPS and IMPS if enabled
2530 //before starting Go
2531 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2532 {
2533 if(VOS_STATUS_E_FAILURE ==
2534 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2535 {
2536 //Fail to Exit BMPS
2537 VOS_ASSERT(0);
2538 }
2539 }
2540
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002541 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2542 (pConfig->apRandomBssidEnabled))
2543 {
2544 /* To meet Android requirements create a randomized
2545 MAC address of the form 02:1A:11:Fx:xx:xx */
2546 get_random_bytes(&ndev->dev_addr[3], 3);
2547 ndev->dev_addr[0] = 0x02;
2548 ndev->dev_addr[1] = 0x1A;
2549 ndev->dev_addr[2] = 0x11;
2550 ndev->dev_addr[3] |= 0xF0;
2551 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2552 VOS_MAC_ADDR_SIZE);
2553 pr_info("wlan: Generated HotSpot BSSID "
2554 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2555 ndev->dev_addr[0],
2556 ndev->dev_addr[1],
2557 ndev->dev_addr[2],
2558 ndev->dev_addr[3],
2559 ndev->dev_addr[4],
2560 ndev->dev_addr[5]);
2561 }
2562
Jeff Johnson295189b2012-06-20 16:38:30 -07002563 hdd_set_ap_ops( pAdapter->dev );
2564
2565 status = hdd_init_ap_mode(pAdapter);
2566 if(status != VOS_STATUS_SUCCESS)
2567 {
2568 hddLog(VOS_TRACE_LEVEL_FATAL,
2569 "%s: Error initializing the ap mode", __func__);
2570 return -EINVAL;
2571 }
2572 hdd_set_conparam(1);
2573
Jeff Johnson295189b2012-06-20 16:38:30 -07002574 /*interface type changed update in wiphy structure*/
2575 if(wdev)
2576 {
2577 wdev->iftype = type;
2578 pHddCtx->change_iface = type;
2579 }
2580 else
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2584 return -EINVAL;
2585 }
2586 goto done;
2587 }
2588
2589 default:
2590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2591 __func__);
2592 return -EOPNOTSUPP;
2593 }
2594 }
2595 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002596 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 )
2598 {
2599 switch(type)
2600 {
2601 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002602 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002604 hdd_stop_adapter( pHddCtx, pAdapter );
2605 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002606 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002607 //Check for sub-string p2p to confirm its a p2p interface
2608 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002609 {
2610 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2611 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2612 }
2613 else
2614 {
2615 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002616 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002618 hdd_set_conparam(0);
2619 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002620 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2621 hdd_set_station_ops( pAdapter->dev );
2622 status = hdd_init_station_mode( pAdapter );
2623 if( VOS_STATUS_SUCCESS != status )
2624 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002625 /* In case of JB, for P2P-GO, only change interface will be called,
2626 * This is the right place to enable back bmps_imps()
2627 */
2628 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 goto done;
2630 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002631 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002632 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002633 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2634 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002635 goto done;
2636 default:
2637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2638 __func__);
2639 return -EOPNOTSUPP;
2640
2641 }
2642
2643 }
2644 else
2645 {
2646 return -EOPNOTSUPP;
2647 }
2648
2649
2650 if(pRoamProfile)
2651 {
2652 if ( LastBSSType != pRoamProfile->BSSType )
2653 {
2654 /*interface type changed update in wiphy structure*/
2655 wdev->iftype = type;
2656
2657 /*the BSS mode changed, We need to issue disconnect
2658 if connected or in IBSS disconnect state*/
2659 if ( hdd_connGetConnectedBssType(
2660 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2661 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2662 {
2663 /*need to issue a disconnect to CSR.*/
2664 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2665 if( eHAL_STATUS_SUCCESS ==
2666 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2667 pAdapter->sessionId,
2668 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2669 {
2670 wait_for_completion_interruptible_timeout(
2671 &pAdapter->disconnect_comp_var,
2672 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2673 }
2674 }
2675 }
2676 }
2677
2678done:
2679 /*set bitmask based on updated value*/
2680 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2681#ifdef WLAN_BTAMP_FEATURE
2682 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2683 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2684 {
2685 //we are ok to do AMP
2686 pHddCtx->isAmpAllowed = VOS_TRUE;
2687 }
2688#endif //WLAN_BTAMP_FEATURE
2689 EXIT();
2690 return 0;
2691}
2692
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002693#ifdef FEATURE_WLAN_TDLS
2694static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2695 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2696{
2697 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2698 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2699 VOS_STATUS status;
2700
2701 ENTER();
2702
2703 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "Invalid arguments");
2707 return -EINVAL;
2708 }
2709 if (pHddCtx->isLogpInProgress)
2710 {
2711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2712 "%s:LOGP in Progress. Ignore!!!", __func__);
2713 return -EBUSY;
2714 }
2715
2716 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
2717 FALSE == sme_IsFeatureSupportedByFW(TDLS))
2718 {
2719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2720 "TDLS Disabled in INI OR not enabled in FW.\
2721 Cannot process TDLS commands \n");
2722 return -ENOTSUPP;
2723 }
2724
2725 if (wlan_hdd_tdls_is_progress(pAdapter, mac, TRUE))
2726 {
2727 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2728 "%s: TDLS setup is ongoing. Request declined.",__func__);
2729 return -EPERM;
2730 }
2731
2732 /* first to check if we reached to maximum supported TDLS peer.
2733 TODO: for now, return -EPERM looks working fine,
2734 but need to check if any other errno fit into this category.*/
2735 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2736 {
2737 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2738 "%s: TDLS Max peer already connected. Request declined. \n",
2739 __func__);
2740 return -EPERM;
2741 }
2742 else
2743 {
2744 hddTdlsPeer_t *pTdlsPeer;
2745 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2746 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
2747 {
2748 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2749 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
2750 __func__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
2751 return -EPERM;
2752 }
2753 }
2754
2755 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
2756
2757 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2758
2759 if (!update)
2760 {
2761 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2762 pAdapter->sessionId, mac);
2763 }
2764 else
2765 {
2766 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2767 pAdapter->sessionId, mac, StaParams);
2768 }
2769
2770 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2771 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2772
2773 if (!status)
2774 {
2775 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2776 "%s: timeout waiting for tdls add station indication",
2777 __func__);
2778 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2779 return -EPERM;
2780 }
2781 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2782 {
2783 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2784 "%s: Add Station is unsucessful", __func__);
2785 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2786 return -EPERM;
2787 }
2788
2789 return 0;
2790}
2791#endif
2792
Jeff Johnson295189b2012-06-20 16:38:30 -07002793static int wlan_hdd_change_station(struct wiphy *wiphy,
2794 struct net_device *dev,
2795 u8 *mac,
2796 struct station_parameters *params)
2797{
2798 VOS_STATUS status = VOS_STATUS_SUCCESS;
2799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2800 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002801#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002802 tCsrStaParams StaParams = {0};
2803 u32 set;
2804 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002805#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002806 ENTER();
2807
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002808 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2809 {
2810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2811 "%s:LOGP in Progress. Ignore!!!", __func__);
2812 return -EAGAIN;
2813 }
2814
Jeff Johnson295189b2012-06-20 16:38:30 -07002815 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2816
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002817#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002818 StaParams.capability = params->capability;
2819 StaParams.uapsd_queues = params->uapsd_queues;
2820 StaParams.max_sp = params->max_sp;
2821
2822 if (0 != params->ext_capab_len)
2823 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2824 sizeof(StaParams.extn_capability));
2825
2826 if (NULL != params->ht_capa)
2827 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
2828
2829 StaParams.supported_rates_len = params->supported_rates_len;
2830
2831 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2832 * The supported_rates array , for all the structures propogating till Add Sta
2833 * to the firmware has to be modified , if the supplicant (ieee80211) is
2834 * modified to send more rates.
2835 */
2836
2837 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2838 */
2839 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2840 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2841
2842 if (0 != StaParams.supported_rates_len) {
2843 int i = 0;
2844 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2845 StaParams.supported_rates_len);
2846 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2847 "Supported Rates with Length %d", StaParams.supported_rates_len);
2848 for (i=0; i < StaParams.supported_rates_len; i++)
2849 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2850 "[%d]: %0x", i, StaParams.supported_rates[i]);
2851 }
2852
2853 if (NULL != params->vht_capa)
2854 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
2855
2856 set = params->sta_flags_set;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002857#endif
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002858
2859 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2860 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002861 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002862 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002863 {
2864 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2865 WLANTL_STA_AUTHENTICATED);
2866
2867 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002868 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002869 return -EINVAL;
2870 }
2871 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002872#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002873 else if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ) {
2874 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2875 if (0 != params->ext_capab_len ) {
2876 /*Define A Macro : TODO Sunil*/
2877 if ((1<<4) & StaParams.extn_capability[3]) {
2878 isBufSta = 1;
2879 }
2880 }
2881 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2882 "%s: TDLS Peer Parameters.", __func__);
2883 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2884 "uapsd_queues: %0x\n", params->uapsd_queues);
2885 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2886 "max_sp: %0x\n", params->max_sp);
2887 if (params->ht_capa) {
2888 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2889 "ht_capa->cap_info: %0x\n", params->ht_capa->cap_info);
2890 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2891 "ht_capa->ampdu_params_info: %0x\n",
2892 params->ht_capa->ampdu_params_info);
2893 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2894 "ht_capa->extended_capabilities: %0x\n",
2895 params->ht_capa->extended_ht_cap_info);
2896 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2897 "ht_capa->tx_BF_cap_info: %0x\n",
2898 params->ht_capa->tx_BF_cap_info);
2899 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2900 "ht_capa->antenna_selection_info: %0x\n",
2901 params->ht_capa->antenna_selection_info);
2902 }
2903 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2904 "params->capability: %0x\n",params->capability);
2905 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2906 "params->ext_capab_len: %0x\n",params->ext_capab_len);
2907 if (0 != params->ext_capab_len )
2908 {
2909 int i =0;
2910 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2911 "Extended capabilities:");
2912 for (i=0; i < params->ext_capab_len; i++)
2913 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2914 "[%d]: %0x", i, params->ext_capab[i]);
2915 }
2916 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
2917 // params->max_sp, isBufSta);
2918 if (VOS_STATUS_SUCCESS != status) {
2919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2920 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
2921 return -EINVAL;
2922 }
2923 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2924 "ht_capa->cap_info: %0x\n", StaParams.HTCap.capInfo);
2925 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
2926
2927 if (VOS_STATUS_SUCCESS != status) {
2928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2929 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
2930 return -EINVAL;
2931 }
2932 }
2933 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002935
Jeff Johnsone7245742012-09-05 17:12:55 -07002936 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002937 return status;
2938}
2939
2940/*
2941 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2942 * This function is used to get peer station index in IBSS mode
2943 */
2944static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2945{
2946 u8 idx = 0;
2947 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2948 ENTER();
2949 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2950 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2951 {
2952 if ( (0 !=
2953 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2954 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2955 temp, VOS_MAC_ADDR_SIZE)
2956 )
2957 {
2958 return idx;
2959 }
2960 }
2961 return idx;
2962}
2963
2964
2965/*
2966 * FUNCTION: wlan_hdd_cfg80211_add_key
2967 * This function is used to initialize the key information
2968 */
2969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2970static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2971 struct net_device *ndev,
2972 u8 key_index, bool pairwise,
2973 const u8 *mac_addr,
2974 struct key_params *params
2975 )
2976#else
2977static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2978 struct net_device *ndev,
2979 u8 key_index, const u8 *mac_addr,
2980 struct key_params *params
2981 )
2982#endif
2983{
2984 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2985 tCsrRoamSetKey setKey;
2986 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2987 int status = 0;
2988 v_U32_t roamId= 0xFF;
2989 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2990 hdd_hostapd_state_t *pHostapdState;
2991 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002992 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002993
2994 ENTER();
2995
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002996 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2997 {
2998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "%s:LOGP in Progress. Ignore!!!", __func__);
3000 return -EAGAIN;
3001 }
3002
Jeff Johnson295189b2012-06-20 16:38:30 -07003003 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3004 __func__,pAdapter->device_mode);
3005
3006 if (CSR_MAX_NUM_KEY <= key_index)
3007 {
3008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3009 key_index);
3010
3011 return -EINVAL;
3012 }
3013
3014 hddLog(VOS_TRACE_LEVEL_INFO,
3015 "%s: called with key index = %d & key length %d",
3016 __func__, key_index, params->key_len);
3017
3018 /*extract key idx, key len and key*/
3019 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3020 setKey.keyId = key_index;
3021 setKey.keyLength = params->key_len;
3022 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3023
3024 switch (params->cipher)
3025 {
3026 case WLAN_CIPHER_SUITE_WEP40:
3027 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3028 break;
3029
3030 case WLAN_CIPHER_SUITE_WEP104:
3031 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3032 break;
3033
3034 case WLAN_CIPHER_SUITE_TKIP:
3035 {
3036 u8 *pKey = &setKey.Key[0];
3037 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3038
3039 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3040
3041 /*Supplicant sends the 32bytes key in this order
3042
3043 |--------------|----------|----------|
3044 | Tk1 |TX-MIC | RX Mic |
3045 |--------------|----------|----------|
3046 <---16bytes---><--8bytes--><--8bytes-->
3047
3048 */
3049 /*Sme expects the 32 bytes key to be in the below order
3050
3051 |--------------|----------|----------|
3052 | Tk1 |RX-MIC | TX Mic |
3053 |--------------|----------|----------|
3054 <---16bytes---><--8bytes--><--8bytes-->
3055 */
3056 /* Copy the Temporal Key 1 (TK1) */
3057 vos_mem_copy(pKey, params->key,16);
3058
3059 /*Copy the rx mic first*/
3060 vos_mem_copy(&pKey[16],&params->key[24],8);
3061
3062 /*Copy the tx mic */
3063 vos_mem_copy(&pKey[24],&params->key[16],8);
3064
3065
3066 break;
3067 }
3068
3069 case WLAN_CIPHER_SUITE_CCMP:
3070 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3071 break;
3072
3073#ifdef FEATURE_WLAN_WAPI
3074 case WLAN_CIPHER_SUITE_SMS4:
3075 {
3076 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3077 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3078 params->key, params->key_len);
3079 return 0;
3080 }
3081#endif
3082#ifdef FEATURE_WLAN_CCX
3083 case WLAN_CIPHER_SUITE_KRK:
3084 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3085 break;
3086#endif
3087 default:
3088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3089 __func__, params->cipher);
3090 return -EOPNOTSUPP;
3091 }
3092
3093 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3094 __func__, setKey.encType);
3095
3096
3097
3098 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003099 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 )
3101 {
3102
3103
3104 if (
3105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3106 (!pairwise)
3107#else
3108 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3109#endif
3110 )
3111 {
3112 /* set group key*/
3113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003114 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003115 __func__, __LINE__);
3116 setKey.keyDirection = eSIR_RX_ONLY;
3117 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3118 }
3119 else
3120 {
3121 /* set pairwise key*/
3122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3123 "%s- %d: setting pairwise key",
3124 __func__, __LINE__);
3125 setKey.keyDirection = eSIR_TX_RX;
3126 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3127 }
3128
3129 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3130 if( pHostapdState->bssState == BSS_START )
3131 {
3132 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3133
3134 if ( status != eHAL_STATUS_SUCCESS )
3135 {
3136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3137 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3138 __LINE__, status );
3139 }
3140 }
3141
3142 /* Saving WEP keys */
3143 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3144 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3145 {
3146 //Save the wep key in ap context. Issue setkey after the BSS is started.
3147 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3148 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3149 }
3150 else
3151 {
3152 //Save the key in ap context. Issue setkey after the BSS is started.
3153 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3154 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3155 }
3156 }
3157 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003158 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 )
3160 {
3161 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3162 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3163
3164 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3165
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003166 pWextState->roamProfile.Keys.defaultIndex = key_index;
3167
3168
Jeff Johnson295189b2012-06-20 16:38:30 -07003169 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3170 params->key, params->key_len);
3171
3172 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3173
3174 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3175 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3176 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3177 )
3178 &&
3179 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3180 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3181 )
3182 )
3183 {
3184 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3185 * interface, copy bssid for pairwise key and group macaddr for
3186 * group key initialization*/
3187
3188 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3189
3190 pWextState->roamProfile.negotiatedUCEncryptionType =
3191 pHddStaCtx->conn_info.ucEncryptionType =
3192 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3193 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3194 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3195
3196
3197 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3198 "%s: Negotiated encryption type %d", __func__,
3199 pWextState->roamProfile.negotiatedUCEncryptionType);
3200
3201 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3202 &pWextState->roamProfile, true);
3203 setKey.keyLength = 0;
3204 setKey.keyDirection = eSIR_TX_RX;
3205
3206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3207 if (pairwise)
3208 {
3209#endif
3210 if (mac_addr)
3211 {
3212 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3213 }
3214 else
3215 {
3216 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3217 * and peerMacAddress in case of IBSS*/
3218 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3219 {
3220 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3221 if (HDD_MAX_NUM_IBSS_STA != staidx)
3222 {
3223 vos_mem_copy(setKey.peerMac,
3224 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3225 WNI_CFG_BSSID_LEN);
3226
3227 }
3228 else
3229 {
3230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3231 __func__);
3232 return -EOPNOTSUPP;
3233 }
3234 }
3235 else
3236 {
3237 vos_mem_copy(setKey.peerMac,
3238 &pHddStaCtx->conn_info.bssId[0],
3239 WNI_CFG_BSSID_LEN);
3240 }
3241 }
3242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3243 }
3244 else
3245 {
3246 /* set group key*/
3247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3248 "%s- %d: setting Group key",
3249 __func__, __LINE__);
3250 setKey.keyDirection = eSIR_RX_ONLY;
3251 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3252 }
3253#endif
3254 }
3255 else if (
3256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3257 (!pairwise)
3258#else
3259 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3260#endif
3261 )
3262 {
3263 /* set group key*/
3264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3265 "%s- %d: setting Group key",
3266 __func__, __LINE__);
3267 setKey.keyDirection = eSIR_RX_ONLY;
3268 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3269 }
3270 else
3271 {
3272 /* set pairwise key*/
3273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3274 "%s- %d: setting pairwise key",
3275 __func__, __LINE__);
3276 setKey.keyDirection = eSIR_TX_RX;
3277 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3278 }
3279
3280 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3281 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3282 __func__, setKey.peerMac[0], setKey.peerMac[1],
3283 setKey.peerMac[2], setKey.peerMac[3],
3284 setKey.peerMac[4], setKey.peerMac[5],
3285 setKey.keyDirection);
3286
3287 vos_status = wlan_hdd_check_ula_done(pAdapter);
3288
3289 if ( vos_status != VOS_STATUS_SUCCESS )
3290 {
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3292 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3293 __LINE__, vos_status );
3294
3295 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3296
3297 return -EINVAL;
3298
3299 }
3300
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003301#ifdef WLAN_FEATURE_VOWIFI_11R
3302 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3303 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003304 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303305 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003306 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303307 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003308 }
3309#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003310
3311 /* issue set key request to SME*/
3312 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3313 pAdapter->sessionId, &setKey, &roamId );
3314
3315 if ( 0 != status )
3316 {
3317 hddLog(VOS_TRACE_LEVEL_ERROR,
3318 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3319 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3320 return -EINVAL;
3321 }
3322
3323
3324 /* in case of IBSS as there was no information available about WEP keys during
3325 * IBSS join, group key intialized with NULL key, so re-initialize group key
3326 * with correct value*/
3327 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3328 !( ( IW_AUTH_KEY_MGMT_802_1X
3329 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3330 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3331 )
3332 &&
3333 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3334 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3335 )
3336 )
3337 {
3338 setKey.keyDirection = eSIR_RX_ONLY;
3339 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3340
3341 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3342 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3343 __func__, setKey.peerMac[0], setKey.peerMac[1],
3344 setKey.peerMac[2], setKey.peerMac[3],
3345 setKey.peerMac[4], setKey.peerMac[5],
3346 setKey.keyDirection);
3347
3348 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3349 pAdapter->sessionId, &setKey, &roamId );
3350
3351 if ( 0 != status )
3352 {
3353 hddLog(VOS_TRACE_LEVEL_ERROR,
3354 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3355 __func__, status);
3356 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3357 return -EINVAL;
3358 }
3359 }
3360 }
3361
3362 return 0;
3363}
3364
3365/*
3366 * FUNCTION: wlan_hdd_cfg80211_get_key
3367 * This function is used to get the key information
3368 */
3369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3370static int wlan_hdd_cfg80211_get_key(
3371 struct wiphy *wiphy,
3372 struct net_device *ndev,
3373 u8 key_index, bool pairwise,
3374 const u8 *mac_addr, void *cookie,
3375 void (*callback)(void *cookie, struct key_params*)
3376 )
3377#else
3378static int wlan_hdd_cfg80211_get_key(
3379 struct wiphy *wiphy,
3380 struct net_device *ndev,
3381 u8 key_index, const u8 *mac_addr, void *cookie,
3382 void (*callback)(void *cookie, struct key_params*)
3383 )
3384#endif
3385{
3386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3387 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3388 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3389 struct key_params params;
3390
3391 ENTER();
3392
3393 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3394 __func__,pAdapter->device_mode);
3395
3396 memset(&params, 0, sizeof(params));
3397
3398 if (CSR_MAX_NUM_KEY <= key_index)
3399 {
3400 return -EINVAL;
3401 }
3402
3403 switch(pRoamProfile->EncryptionType.encryptionType[0])
3404 {
3405 case eCSR_ENCRYPT_TYPE_NONE:
3406 params.cipher = IW_AUTH_CIPHER_NONE;
3407 break;
3408
3409 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3410 case eCSR_ENCRYPT_TYPE_WEP40:
3411 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3412 break;
3413
3414 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3415 case eCSR_ENCRYPT_TYPE_WEP104:
3416 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3417 break;
3418
3419 case eCSR_ENCRYPT_TYPE_TKIP:
3420 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3421 break;
3422
3423 case eCSR_ENCRYPT_TYPE_AES:
3424 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3425 break;
3426
3427 default:
3428 params.cipher = IW_AUTH_CIPHER_NONE;
3429 break;
3430 }
3431
3432 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3433 params.seq_len = 0;
3434 params.seq = NULL;
3435 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3436 callback(cookie, &params);
3437 return 0;
3438}
3439
3440/*
3441 * FUNCTION: wlan_hdd_cfg80211_del_key
3442 * This function is used to delete the key information
3443 */
3444#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3445static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3446 struct net_device *ndev,
3447 u8 key_index,
3448 bool pairwise,
3449 const u8 *mac_addr
3450 )
3451#else
3452static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3453 struct net_device *ndev,
3454 u8 key_index,
3455 const u8 *mac_addr
3456 )
3457#endif
3458{
3459 int status = 0;
3460
3461 //This code needs to be revisited. There is sme_removeKey API, we should
3462 //plan to use that. After the change to use correct index in setkey,
3463 //it is observed that this is invalidating peer
3464 //key index whenever re-key is done. This is affecting data link.
3465 //It should be ok to ignore del_key.
3466#if 0
3467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3468 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3469 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3470 tCsrRoamSetKey setKey;
3471 v_U32_t roamId= 0xFF;
3472
3473 ENTER();
3474
3475 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3476 __func__,pAdapter->device_mode);
3477
3478 if (CSR_MAX_NUM_KEY <= key_index)
3479 {
3480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3481 key_index);
3482
3483 return -EINVAL;
3484 }
3485
3486 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3487 setKey.keyId = key_index;
3488
3489 if (mac_addr)
3490 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3491 else
3492 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3493
3494 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3495
3496 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003497 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003498 )
3499 {
3500
3501 hdd_hostapd_state_t *pHostapdState =
3502 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3503 if( pHostapdState->bssState == BSS_START)
3504 {
3505 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3506
3507 if ( status != eHAL_STATUS_SUCCESS )
3508 {
3509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3510 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3511 __LINE__, status );
3512 }
3513 }
3514 }
3515 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003516 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 )
3518 {
3519 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3520
3521 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3522
3523 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3524 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3525 __func__, setKey.peerMac[0], setKey.peerMac[1],
3526 setKey.peerMac[2], setKey.peerMac[3],
3527 setKey.peerMac[4], setKey.peerMac[5]);
3528 if(pAdapter->sessionCtx.station.conn_info.connState ==
3529 eConnectionState_Associated)
3530 {
3531 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3532 pAdapter->sessionId, &setKey, &roamId );
3533
3534 if ( 0 != status )
3535 {
3536 hddLog(VOS_TRACE_LEVEL_ERROR,
3537 "%s: sme_RoamSetKey failure, returned %d",
3538 __func__, status);
3539 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3540 return -EINVAL;
3541 }
3542 }
3543 }
3544#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003545 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 return status;
3547}
3548
3549/*
3550 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3551 * This function is used to set the default tx key index
3552 */
3553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3554static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3555 struct net_device *ndev,
3556 u8 key_index,
3557 bool unicast, bool multicast)
3558#else
3559static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3560 struct net_device *ndev,
3561 u8 key_index)
3562#endif
3563{
3564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3565 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3566 int status = 0;
3567 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3568
3569 ENTER();
3570
3571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3572 __func__,pAdapter->device_mode, key_index);
3573
3574 if (CSR_MAX_NUM_KEY <= key_index)
3575 {
3576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3577 key_index);
3578
3579 return -EINVAL;
3580 }
3581
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003582 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3583 {
3584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3585 "%s:LOGP in Progress. Ignore!!!", __func__);
3586 return -EAGAIN;
3587 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003588
3589 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003590 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003591 )
3592 {
3593 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3594 (eCSR_ENCRYPT_TYPE_TKIP !=
3595 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3596 (eCSR_ENCRYPT_TYPE_AES !=
3597 pWextState->roamProfile.EncryptionType.encryptionType[0])
3598 )
3599 {
3600 /* if default key index is not same as previous one,
3601 * then update the default key index */
3602
3603 tCsrRoamSetKey setKey;
3604 v_U32_t roamId= 0xFF;
3605 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3606
3607 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3608 __func__, key_index);
3609
3610 Keys->defaultIndex = (u8)key_index;
3611 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3612 setKey.keyId = key_index;
3613 setKey.keyLength = Keys->KeyLength[key_index];
3614
3615 vos_mem_copy(&setKey.Key[0],
3616 &Keys->KeyMaterial[key_index][0],
3617 Keys->KeyLength[key_index]);
3618
3619 setKey.keyDirection = eSIR_TX_ONLY;
3620
3621 vos_mem_copy(setKey.peerMac,
3622 &pHddStaCtx->conn_info.bssId[0],
3623 WNI_CFG_BSSID_LEN);
3624
3625 setKey.encType =
3626 pWextState->roamProfile.EncryptionType.encryptionType[0];
3627
3628 /* issue set key request */
3629 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3630 pAdapter->sessionId, &setKey, &roamId );
3631
3632 if ( 0 != status )
3633 {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "%s: sme_RoamSetKey failed, returned %d", __func__,
3636 status);
3637 return -EINVAL;
3638 }
3639 }
3640 }
3641
3642 /* In SoftAp mode setting key direction for default mode */
3643 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3644 {
3645 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3646 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3647 (eCSR_ENCRYPT_TYPE_AES !=
3648 pWextState->roamProfile.EncryptionType.encryptionType[0])
3649 )
3650 {
3651 /* Saving key direction for default key index to TX default */
3652 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3653 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3654 }
3655 }
3656
3657 return status;
3658}
3659
Jeff Johnson295189b2012-06-20 16:38:30 -07003660/*
3661 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3662 * This function is used to inform the BSS details to nl80211 interface.
3663 */
3664static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3665 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3666{
3667 struct net_device *dev = pAdapter->dev;
3668 struct wireless_dev *wdev = dev->ieee80211_ptr;
3669 struct wiphy *wiphy = wdev->wiphy;
3670 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3671 int chan_no;
3672 int ie_length;
3673 const char *ie;
3674 unsigned int freq;
3675 struct ieee80211_channel *chan;
3676 int rssi = 0;
3677 struct cfg80211_bss *bss = NULL;
3678
3679 ENTER();
3680
3681 if( NULL == pBssDesc )
3682 {
3683 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3684 return bss;
3685 }
3686
3687 chan_no = pBssDesc->channelId;
3688 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3689 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3690
3691 if( NULL == ie )
3692 {
3693 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3694 return bss;
3695 }
3696
3697#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3698 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3699 {
3700 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3701 }
3702 else
3703 {
3704 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3705 }
3706#else
3707 freq = ieee80211_channel_to_frequency(chan_no);
3708#endif
3709
3710 chan = __ieee80211_get_channel(wiphy, freq);
3711
3712 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3713 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3714 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3715 if (bss == NULL)
3716 {
3717 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3718
3719 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3720 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3721 pBssDesc->capabilityInfo,
3722 pBssDesc->beaconInterval, ie, ie_length,
3723 rssi, GFP_KERNEL ));
3724}
3725 else
3726 {
3727 return bss;
3728 }
3729}
3730
3731
3732
3733/*
3734 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3735 * This function is used to inform the BSS details to nl80211 interface.
3736 */
3737struct cfg80211_bss*
3738wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3739 tSirBssDescription *bss_desc
3740 )
3741{
3742 /*
3743 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3744 already exists in bss data base of cfg80211 for that particular BSS ID.
3745 Using cfg80211_inform_bss_frame to update the bss entry instead of
3746 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3747 now there is no possibility to get the mgmt(probe response) frame from PE,
3748 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3749 cfg80211_inform_bss_frame.
3750 */
3751 struct net_device *dev = pAdapter->dev;
3752 struct wireless_dev *wdev = dev->ieee80211_ptr;
3753 struct wiphy *wiphy = wdev->wiphy;
3754 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003755#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3756 qcom_ie_age *qie_age = NULL;
3757 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3758#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003759 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003761 const char *ie =
3762 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3763 unsigned int freq;
3764 struct ieee80211_channel *chan;
3765 struct ieee80211_mgmt *mgmt =
3766 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3767 struct cfg80211_bss *bss_status = NULL;
3768 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3769 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003770#ifdef WLAN_OPEN_SOURCE
3771 struct timespec ts;
3772#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003773
3774 ENTER();
3775
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003776 if (!mgmt)
3777 return NULL;
3778
Jeff Johnson295189b2012-06-20 16:38:30 -07003779 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003780
3781#ifdef WLAN_OPEN_SOURCE
3782 /* Android does not want the timestamp from the frame.
3783 Instead it wants a monotonic increasing value */
3784 get_monotonic_boottime(&ts);
3785 mgmt->u.probe_resp.timestamp =
3786 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3787#else
3788 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003789 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3790 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003791
3792#endif
3793
Jeff Johnson295189b2012-06-20 16:38:30 -07003794 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3795 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003796
3797#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3798 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3799 /* Assuming this is the last IE, copy at the end */
3800 ie_length -=sizeof(qcom_ie_age);
3801 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3802 qie_age->element_id = QCOM_VENDOR_IE_ID;
3803 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3804 qie_age->oui_1 = QCOM_OUI1;
3805 qie_age->oui_2 = QCOM_OUI2;
3806 qie_age->oui_3 = QCOM_OUI3;
3807 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3808 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3809#endif
3810
Jeff Johnson295189b2012-06-20 16:38:30 -07003811 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3812
3813 mgmt->frame_control |=
3814 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3815
3816#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3817 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3818 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3819 {
3820 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3821 }
3822 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3823 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3824
3825 {
3826 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3827 }
3828 else
3829 {
3830 kfree(mgmt);
3831 return NULL;
3832 }
3833#else
3834 freq = ieee80211_channel_to_frequency(chan_no);
3835#endif
3836 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003837 /*when the band is changed on the fly using the GUI, three things are done
3838 * 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)
3839 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3840 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3841 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3842 * and discards the channels correponding to previous band and calls back with zero bss results.
3843 * 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
3844 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3845 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3846 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3847 * So drop the bss and continue to next bss.
3848 */
3849 if(chan == NULL)
3850 {
3851 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3852 return NULL;
3853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003854 /*To keep the rssi icon of the connected AP in the scan window
3855 *and the rssi icon of the wireless networks in sync
3856 * */
3857 if (( eConnectionState_Associated ==
3858 pAdapter->sessionCtx.station.conn_info.connState ) &&
3859 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3860 pAdapter->sessionCtx.station.conn_info.bssId,
3861 WNI_CFG_BSSID_LEN)))
3862 {
3863 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3864 rssi = (pAdapter->rssi * 100);
3865 }
3866 else
3867 {
3868 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3869 }
3870
3871 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3872 frame_len, rssi, GFP_KERNEL);
3873 kfree(mgmt);
3874 return bss_status;
3875}
3876
3877/*
3878 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3879 * This function is used to update the BSS data base of CFG8011
3880 */
3881struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3882 tCsrRoamInfo *pRoamInfo
3883 )
3884{
3885 tCsrRoamConnectedProfile roamProfile;
3886 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3887 struct cfg80211_bss *bss = NULL;
3888
3889 ENTER();
3890
3891 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3892 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3893
3894 if (NULL != roamProfile.pBssDesc)
3895 {
3896 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3897 &roamProfile);
3898
3899 if (NULL == bss)
3900 {
3901 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3902 __func__);
3903 }
3904
3905 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3906 }
3907 else
3908 {
3909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3910 __func__);
3911 }
3912 return bss;
3913}
3914
3915/*
3916 * FUNCTION: wlan_hdd_cfg80211_update_bss
3917 */
3918static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3919 hdd_adapter_t *pAdapter
3920 )
3921{
3922 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3923 tCsrScanResultInfo *pScanResult;
3924 eHalStatus status = 0;
3925 tScanResultHandle pResult;
3926 struct cfg80211_bss *bss_status = NULL;
3927
3928 ENTER();
3929
3930 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3931 {
3932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3933 return -EAGAIN;
3934 }
3935
3936 /*
3937 * start getting scan results and populate cgf80211 BSS database
3938 */
3939 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3940
3941 /* no scan results */
3942 if (NULL == pResult)
3943 {
3944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3945 return status;
3946 }
3947
3948 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3949
3950 while (pScanResult)
3951 {
3952 /*
3953 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3954 * entry already exists in bss data base of cfg80211 for that
3955 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3956 * bss entry instead of cfg80211_inform_bss, But this call expects
3957 * mgmt packet as input. As of now there is no possibility to get
3958 * the mgmt(probe response) frame from PE, converting bss_desc to
3959 * ieee80211_mgmt(probe response) and passing to c
3960 * fg80211_inform_bss_frame.
3961 * */
3962
3963 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3964 &pScanResult->BssDescriptor);
3965
3966
3967 if (NULL == bss_status)
3968 {
3969 hddLog(VOS_TRACE_LEVEL_INFO,
3970 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3971 }
3972 else
3973 {
3974 cfg80211_put_bss(bss_status);
3975 }
3976
3977 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3978 }
3979
3980 sme_ScanResultPurge(hHal, pResult);
3981
3982 return 0;
3983}
3984
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003985void
3986hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3987{
3988 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003989 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3990 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3991 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003992} /****** end hddPrintMacAddr() ******/
3993
3994void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003995hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003996{
3997 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003998 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3999 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4000 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4001 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004002} /****** end hddPrintPmkId() ******/
4003
4004//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4005//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4006
4007//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4008//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4009
4010#define dump_bssid(bssid) \
4011 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004012 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4013 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4014 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004015 }
4016
4017#define dump_pmkid(pMac, pmkid) \
4018 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004019 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4020 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4021 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004022 }
4023
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004024#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004025/*
4026 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4027 * This function is used to notify the supplicant of a new PMKSA candidate.
4028 */
4029int wlan_hdd_cfg80211_pmksa_candidate_notify(
4030 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
4031 int index, bool preauth )
4032{
Jeff Johnsone7245742012-09-05 17:12:55 -07004033#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004034 struct net_device *dev = pAdapter->dev;
4035
4036 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004037 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004038
4039 if( NULL == pRoamInfo )
4040 {
4041 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4042 return -EINVAL;
4043 }
4044
4045 dump_bssid(pRoamInfo->bssid);
4046 cfg80211_pmksa_candidate_notify(dev, index,
4047 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07004048#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004049 return 0;
4050}
4051#endif //FEATURE_WLAN_LFR
4052
Jeff Johnson295189b2012-06-20 16:38:30 -07004053/*
4054 * FUNCTION: hdd_cfg80211_scan_done_callback
4055 * scanning callback function, called after finishing scan
4056 *
4057 */
4058static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
4059 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4060{
4061 struct net_device *dev = (struct net_device *) pContext;
4062 //struct wireless_dev *wdev = dev->ieee80211_ptr;
4063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004064 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4065 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004066 struct cfg80211_scan_request *req = NULL;
4067 int ret = 0;
4068
4069 ENTER();
4070
4071 hddLog(VOS_TRACE_LEVEL_INFO,
4072 "%s called with halHandle = %p, pContext = %p,"
4073 "scanID = %d, returned status = %d\n",
4074 __func__, halHandle, pContext, (int) scanId, (int) status);
4075
4076 //Block on scan req completion variable. Can't wait forever though.
4077 ret = wait_for_completion_interruptible_timeout(
4078 &pScanInfo->scan_req_completion_event,
4079 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4080 if (!ret)
4081 {
4082 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004083 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004084 }
4085
4086 if(pScanInfo->mScanPending != VOS_TRUE)
4087 {
4088 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004089 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004090 }
4091
4092 /* Check the scanId */
4093 if (pScanInfo->scanId != scanId)
4094 {
4095 hddLog(VOS_TRACE_LEVEL_INFO,
4096 "%s called with mismatched scanId pScanInfo->scanId = %d "
4097 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
4098 (int) scanId);
4099 }
4100
Jeff Johnson295189b2012-06-20 16:38:30 -07004101 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
4102 pAdapter);
4103
4104 if (0 > ret)
4105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
4106
4107
4108 /* If any client wait scan result through WEXT
4109 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004110 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004111 {
4112 /* The other scan request waiting for current scan finish
4113 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004114 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004115 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004116 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 }
4118 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004119 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004120 {
4121 struct net_device *dev = pAdapter->dev;
4122 union iwreq_data wrqu;
4123 int we_event;
4124 char *msg;
4125
4126 memset(&wrqu, '\0', sizeof(wrqu));
4127 we_event = SIOCGIWSCAN;
4128 msg = NULL;
4129 wireless_send_event(dev, we_event, &wrqu, msg);
4130 }
4131 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004132 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004133
4134 /* Get the Scan Req */
4135 req = pAdapter->request;
4136
4137 if (!req)
4138 {
4139 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004140 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004141 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004142 }
4143
4144 /*
4145 * setting up 0, just in case.
4146 */
4147 req->n_ssids = 0;
4148 req->n_channels = 0;
4149 req->ie = 0;
4150
Jeff Johnson295189b2012-06-20 16:38:30 -07004151 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004152 /* Scan is no longer pending */
4153 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004154
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004155 /*
4156 * cfg80211_scan_done informing NL80211 about completion
4157 * of scanning
4158 */
4159 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004160 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004161
Jeff Johnsone7245742012-09-05 17:12:55 -07004162allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004163 /* release the wake lock at the end of the scan*/
4164 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004165
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004166 /* Acquire wakelock to handle the case where APP's tries to suspend
4167 * immediatly after the driver gets connect request(i.e after scan)
4168 * from supplicant, this result in app's is suspending and not able
4169 * to process the connect request to AP */
4170 hdd_allow_suspend_timeout(100);
4171
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 EXIT();
4173 return 0;
4174}
4175
4176/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004177 * FUNCTION: hdd_isScanAllowed
4178 * Go through each adapter and check if scan allowed
4179 *
4180 */
4181v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4182{
4183 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4184 hdd_station_ctx_t *pHddStaCtx = NULL;
4185 hdd_adapter_t *pAdapter = NULL;
4186 VOS_STATUS status = 0;
4187 v_U8_t staId = 0;
4188 v_U8_t *staMac = NULL;
4189
4190 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4191
4192 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4193 {
4194 pAdapter = pAdapterNode->pAdapter;
4195
4196 if( pAdapter )
4197 {
4198 hddLog(VOS_TRACE_LEVEL_INFO,
4199 "%s: Adapter with device mode %d exists",
4200 __func__, pAdapter->device_mode);
4201 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4204 {
4205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4206 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4207 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4208 {
4209 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4210 hddLog(VOS_TRACE_LEVEL_ERROR,
4211 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4212 "middle of WPS/EAPOL exchange.", __func__,
4213 staMac[0], staMac[1], staMac[2],
4214 staMac[3], staMac[4], staMac[5]);
4215 return VOS_FALSE;
4216 }
4217 }
4218 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4219 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4220 {
4221 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4222 {
4223 if ((pAdapter->aStaInfo[staId].isUsed) &&
4224 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4225 {
4226 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4227
4228 hddLog(VOS_TRACE_LEVEL_ERROR,
4229 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4230 "middle of WPS/EAPOL exchange.", __func__,
4231 staMac[0], staMac[1], staMac[2],
4232 staMac[3], staMac[4], staMac[5]);
4233 return VOS_FALSE;
4234 }
4235 }
4236 }
4237 }
4238 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4239 pAdapterNode = pNext;
4240 }
4241 hddLog(VOS_TRACE_LEVEL_INFO,
4242 "%s: Scan allowed", __func__);
4243 return VOS_TRUE;
4244}
4245
4246/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004247 * FUNCTION: wlan_hdd_cfg80211_scan
4248 * this scan respond to scan trigger and update cfg80211 scan database
4249 * later, scan dump command can be used to recieve scan results
4250 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004251int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4252#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4253 struct net_device *dev,
4254#endif
4255 struct cfg80211_scan_request *request)
4256{
4257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4258 struct net_device *dev = request->wdev->netdev;
4259#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4261 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4262 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4263 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4264 tCsrScanRequest scanRequest;
4265 tANI_U8 *channelList = NULL, i;
4266 v_U32_t scanId = 0;
4267 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004268 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004269 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004270
4271 ENTER();
4272
4273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4274 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004275
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004276 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004277 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004278 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004279 {
4280 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004281 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4282 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004283 return -EBUSY;
4284 }
4285
Jeff Johnson295189b2012-06-20 16:38:30 -07004286#ifdef WLAN_BTAMP_FEATURE
4287 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004288 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004289 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004290 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004291 "%s: No scanning when AMP is on", __func__);
4292 return -EOPNOTSUPP;
4293 }
4294#endif
4295 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004296 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004297 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004298 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004299 "%s: Not scanning on device_mode = %d",
4300 __func__, pAdapter->device_mode);
4301 return -EOPNOTSUPP;
4302 }
4303
4304 if (TRUE == pScanInfo->mScanPending)
4305 {
4306 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004307 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004308 }
4309
4310 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4311 {
4312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4313 "%s:LOGP in Progress. Ignore!!!", __func__);
4314 return -EAGAIN;
4315 }
4316
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004317 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4318 {
4319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4320 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4321 return -EAGAIN;
4322 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004323 //Don't Allow Scan and return busy if Remain On
4324 //Channel and action frame is pending
4325 //Otherwise Cancel Remain On Channel and allow Scan
4326 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004327 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004328 {
4329 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4330 return -EBUSY;
4331 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004332#ifdef FEATURE_WLAN_TDLS
4333 if (wlan_hdd_tdlsConnectedPeers(pAdapter))
4334 {
4335 tANI_U8 staIdx;
4336
4337 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
4338 {
4339 if (pHddCtx->tdlsConnInfo[staIdx].staId)
4340 {
4341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4342 ("scan: indicate TDLS teadown (staId %d)"), pHddCtx->tdlsConnInfo[staIdx].staId) ;
4343
4344#ifdef CONFIG_TDLS_IMPLICIT
4345 cfg80211_tdls_oper_request(pAdapter->dev,
4346 pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes,
4347 NL80211_TDLS_TEARDOWN,
4348 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
4349 GFP_KERNEL);
4350#endif
4351 }
4352 }
4353 return -EBUSY;
4354 }
4355#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004356
Jeff Johnson295189b2012-06-20 16:38:30 -07004357 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4358 {
4359 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004360 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004361 return -EAGAIN;
4362 }
4363 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4364 {
4365 hddLog(VOS_TRACE_LEVEL_WARN,
4366 "%s: MAX TM Level Scan not allowed", __func__);
4367 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4368 return -EBUSY;
4369 }
4370 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4371
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004372 /* Check if scan is allowed at this point of time.
4373 */
4374 if (!hdd_isScanAllowed(pHddCtx))
4375 {
4376 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4377 return -EBUSY;
4378 }
4379
Jeff Johnson295189b2012-06-20 16:38:30 -07004380 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4381
4382 if (NULL != request)
4383 {
4384 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4385 (int)request->n_ssids);
4386
4387 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4388 * Becasue of this, driver is assuming that this is not wildcard scan and so
4389 * is not aging out the scan results.
4390 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004391 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 {
4393 request->n_ssids = 0;
4394 }
4395
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004396 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004397 {
4398 tCsrSSIDInfo *SsidInfo;
4399 int j;
4400 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4401 /* Allocate num_ssid tCsrSSIDInfo structure */
4402 SsidInfo = scanRequest.SSIDs.SSIDList =
4403 ( tCsrSSIDInfo *)vos_mem_malloc(
4404 request->n_ssids*sizeof(tCsrSSIDInfo));
4405
4406 if(NULL == scanRequest.SSIDs.SSIDList)
4407 {
4408 hddLog(VOS_TRACE_LEVEL_ERROR,
4409 "memory alloc failed SSIDInfo buffer");
4410 return -ENOMEM;
4411 }
4412
4413 /* copy all the ssid's and their length */
4414 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4415 {
4416 /* get the ssid length */
4417 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4418 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4419 SsidInfo->SSID.length);
4420 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4421 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4422 j, SsidInfo->SSID.ssId);
4423 }
4424 /* set the scan type to active */
4425 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4426 }
4427 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4428 {
4429 /* set the scan type to active */
4430 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4431 }
4432 else
4433 {
4434 /*Set the scan type to default type, in this case it is ACTIVE*/
4435 scanRequest.scanType = pScanInfo->scan_mode;
4436 }
4437 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4438 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4439 }
4440 else
4441 {
4442 /* set the scan type to active */
4443 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4444 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4445
4446 /* set min and max channel time to zero */
4447 scanRequest.minChnTime = 0;
4448 scanRequest.maxChnTime = 0;
4449 }
4450
4451 /* set BSSType to default type */
4452 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4453
4454 /*TODO: scan the requested channels only*/
4455
4456 /*Right now scanning all the channels */
4457 if( request )
4458 {
4459 if( request->n_channels )
4460 {
4461 channelList = vos_mem_malloc( request->n_channels );
4462 if( NULL == channelList )
4463 {
4464 status = -ENOMEM;
4465 goto free_mem;
4466 }
4467
4468 for( i = 0 ; i < request->n_channels ; i++ )
4469 channelList[i] = request->channels[i]->hw_value;
4470 }
4471
4472 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4473 scanRequest.ChannelInfo.ChannelList = channelList;
4474
4475 /* set requestType to full scan */
4476 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004477
4478 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4479 * search (Flush on both full scan and social scan but not on single
4480 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4481 */
4482
4483 /* Supplicant does single channel scan after 8-way handshake
4484 * and in that case driver shoudnt flush scan results. If
4485 * driver flushes the scan results here and unfortunately if
4486 * the AP doesnt respond to our probe req then association
4487 * fails which is not desired
4488 */
4489
4490 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4491 {
4492 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4493 pAdapter->sessionId );
4494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004495
4496 if( request->ie_len )
4497 {
4498 /* save this for future association (join requires this) */
4499 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4500 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4501 pScanInfo->scanAddIE.length = request->ie_len;
4502
4503 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004504 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4505 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004506 )
4507 {
4508 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4509 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4510 }
4511
4512 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4513 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4514
Jeff Johnson295189b2012-06-20 16:38:30 -07004515 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4516 request->ie_len);
4517 if (pP2pIe != NULL)
4518 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004519#ifdef WLAN_FEATURE_P2P_DEBUG
4520 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4521 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4522 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4523 {
4524 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4525 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4526 "Go nego completed to Connection is started");
4527 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4528 "for 8way Handshake");
4529 }
4530 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4531 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4532 {
4533 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4534 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4535 "Disconnected state to Connection is started");
4536 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4537 "for 4way Handshake");
4538 }
4539#endif
4540
Jeff Johnsone7245742012-09-05 17:12:55 -07004541 /* no_cck will be set during p2p find to disable 11b rates */
4542 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004543 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 hddLog(VOS_TRACE_LEVEL_INFO,
4545 "%s: This is a P2P Search", __func__);
4546 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004547
Jeff Johnsone7245742012-09-05 17:12:55 -07004548 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4549 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004550 /* set requestType to P2P Discovery */
4551 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004552 }
4553
4554 /*
4555 Skip Dfs Channel in case of P2P Search
4556 if it is set in ini file
4557 */
4558 if(cfg_param->skipDfsChnlInP2pSearch)
4559 {
4560 scanRequest.skipDfsChnlInP2pSearch = 1;
4561 }
4562 else
4563 {
4564 scanRequest.skipDfsChnlInP2pSearch = 0;
4565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004566
Jeff Johnson295189b2012-06-20 16:38:30 -07004567 }
4568 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004569 }
4570 }
4571
4572 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4573
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004574 /* acquire the wakelock to avoid the apps suspend during the scan. To
4575 * address the following issues.
4576 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4577 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4578 * for long time, this result in apps running at full power for long time.
4579 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4580 * be stuck in full power because of resume BMPS
4581 */
4582 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004583
4584 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004585 pAdapter->sessionId, &scanRequest, &scanId,
4586 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004587
Jeff Johnson295189b2012-06-20 16:38:30 -07004588 if (eHAL_STATUS_SUCCESS != status)
4589 {
4590 hddLog(VOS_TRACE_LEVEL_ERROR,
4591 "%s: sme_ScanRequest returned error %d", __func__, status);
4592 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004593 if(eHAL_STATUS_RESOURCES == status)
4594 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004595 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 -07004596 status = -EBUSY;
4597 } else {
4598 status = -EIO;
4599 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004600 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004601 goto free_mem;
4602 }
4603
4604 pScanInfo->mScanPending = TRUE;
4605 pAdapter->request = request;
4606 pScanInfo->scanId = scanId;
4607
4608 complete(&pScanInfo->scan_req_completion_event);
4609
4610free_mem:
4611 if( scanRequest.SSIDs.SSIDList )
4612 {
4613 vos_mem_free(scanRequest.SSIDs.SSIDList);
4614 }
4615
4616 if( channelList )
4617 vos_mem_free( channelList );
4618
4619 EXIT();
4620
4621 return status;
4622}
4623
4624/*
4625 * FUNCTION: wlan_hdd_cfg80211_connect_start
4626 * This function is used to start the association process
4627 */
4628int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004629 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004630{
4631 int status = 0;
4632 hdd_wext_state_t *pWextState;
4633 v_U32_t roamId;
4634 tCsrRoamProfile *pRoamProfile;
4635 eMib_dot11DesiredBssType connectedBssType;
4636 eCsrAuthType RSNAuthType;
4637
4638 ENTER();
4639
4640 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4641
4642 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4643 {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4645 return -EINVAL;
4646 }
4647
4648 pRoamProfile = &pWextState->roamProfile;
4649
4650 if (pRoamProfile)
4651 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004652 int ret = 0;
4653 hdd_station_ctx_t *pHddStaCtx;
4654 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4655 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4656
4657 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4658 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4659 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 {
4661 /* Issue disconnect to CSR */
4662 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4663 if( eHAL_STATUS_SUCCESS ==
4664 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4665 pAdapter->sessionId,
4666 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4667 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004668 ret = wait_for_completion_interruptible_timeout(
4669 &pAdapter->disconnect_comp_var,
4670 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4671 if (0 == ret)
4672 {
4673 VOS_ASSERT(0);
4674 }
4675 }
4676 }
4677 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4678 {
4679 ret = wait_for_completion_interruptible_timeout(
4680 &pAdapter->disconnect_comp_var,
4681 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4682 if (0 == ret)
4683 {
4684 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 }
4686 }
4687
4688 if (HDD_WMM_USER_MODE_NO_QOS ==
4689 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4690 {
4691 /*QoS not enabled in cfg file*/
4692 pRoamProfile->uapsd_mask = 0;
4693 }
4694 else
4695 {
4696 /*QoS enabled, update uapsd mask from cfg file*/
4697 pRoamProfile->uapsd_mask =
4698 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4699 }
4700
4701 pRoamProfile->SSIDs.numOfSSIDs = 1;
4702 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4703 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4704 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4705 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4706 ssid, ssid_len);
4707
4708 if (bssid)
4709 {
4710 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4711 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4712 WNI_CFG_BSSID_LEN);
4713 /* Save BSSID in seperate variable as well, as RoamProfile
4714 BSSID is getting zeroed out in the association process. And in
4715 case of join failure we should send valid BSSID to supplicant
4716 */
4717 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4718 WNI_CFG_BSSID_LEN);
4719 }
4720
4721 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4722 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4723 {
4724 /*set gen ie*/
4725 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4726 /*set auth*/
4727 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4728 }
4729 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4730 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4731 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4732 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4733 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4734 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4735 )
4736 {
4737 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4738 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4739 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4740 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4741 eCSR_AUTH_TYPE_AUTOSWITCH;
4742 pWextState->roamProfile.AuthType.authType[0] =
4743 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4744 }
4745#ifdef FEATURE_WLAN_WAPI
4746 if (pAdapter->wapi_info.nWapiMode)
4747 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004748 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004749 switch (pAdapter->wapi_info.wapiAuthMode)
4750 {
4751 case WAPI_AUTH_MODE_PSK:
4752 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004753 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004754 pAdapter->wapi_info.wapiAuthMode);
4755 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4756 break;
4757 }
4758 case WAPI_AUTH_MODE_CERT:
4759 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004760 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004761 pAdapter->wapi_info.wapiAuthMode);
4762 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4763 break;
4764 }
4765 } // End of switch
4766 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4767 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4768 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004769 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 pRoamProfile->AuthType.numEntries = 1;
4771 pRoamProfile->EncryptionType.numEntries = 1;
4772 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4773 pRoamProfile->mcEncryptionType.numEntries = 1;
4774 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4775 }
4776 }
4777#endif /* FEATURE_WLAN_WAPI */
4778 pRoamProfile->csrPersona = pAdapter->device_mode;
4779
Jeff Johnson32d95a32012-09-10 13:15:23 -07004780 if( operatingChannel )
4781 {
4782 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4783 pRoamProfile->ChannelInfo.numOfChannels = 1;
4784 }
4785
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004786 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4787 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4788 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4789 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004790 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4791 */
4792 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4793 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4794 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004795
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4797 pAdapter->sessionId, pRoamProfile, &roamId);
4798
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004799 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304800 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4801
4802 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4804 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4805 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304806 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004807 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304808 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004809
4810 pRoamProfile->ChannelInfo.ChannelList = NULL;
4811 pRoamProfile->ChannelInfo.numOfChannels = 0;
4812
Jeff Johnson295189b2012-06-20 16:38:30 -07004813 }
4814 else
4815 {
4816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4817 return -EINVAL;
4818 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004819 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004820 return status;
4821}
4822
4823/*
4824 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4825 * This function is used to set the authentication type (OPEN/SHARED).
4826 *
4827 */
4828static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4829 enum nl80211_auth_type auth_type)
4830{
4831 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4832 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4833
4834 ENTER();
4835
4836 /*set authentication type*/
4837 switch (auth_type)
4838 {
4839 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4840 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004841#ifdef WLAN_FEATURE_VOWIFI_11R
4842 case NL80211_AUTHTYPE_FT:
4843#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 hddLog(VOS_TRACE_LEVEL_INFO,
4845 "%s: set authentication type to OPEN", __func__);
4846 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4847 break;
4848
4849 case NL80211_AUTHTYPE_SHARED_KEY:
4850 hddLog(VOS_TRACE_LEVEL_INFO,
4851 "%s: set authentication type to SHARED", __func__);
4852 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4853 break;
4854#ifdef FEATURE_WLAN_CCX
4855 case NL80211_AUTHTYPE_NETWORK_EAP:
4856 hddLog(VOS_TRACE_LEVEL_INFO,
4857 "%s: set authentication type to CCKM WPA", __func__);
4858 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4859 break;
4860#endif
4861
4862
4863 default:
4864 hddLog(VOS_TRACE_LEVEL_ERROR,
4865 "%s: Unsupported authentication type %d", __func__,
4866 auth_type);
4867 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4868 return -EINVAL;
4869 }
4870
4871 pWextState->roamProfile.AuthType.authType[0] =
4872 pHddStaCtx->conn_info.authType;
4873 return 0;
4874}
4875
4876/*
4877 * FUNCTION: wlan_hdd_set_akm_suite
4878 * This function is used to set the key mgmt type(PSK/8021x).
4879 *
4880 */
4881static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4882 u32 key_mgmt
4883 )
4884{
4885 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4886 ENTER();
4887
4888 /*set key mgmt type*/
4889 switch(key_mgmt)
4890 {
4891 case WLAN_AKM_SUITE_PSK:
4892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4893 __func__);
4894 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4895 break;
4896
4897 case WLAN_AKM_SUITE_8021X:
4898 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4899 __func__);
4900 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4901 break;
4902#ifdef FEATURE_WLAN_CCX
4903#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4904#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4905 case WLAN_AKM_SUITE_CCKM:
4906 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4907 __func__);
4908 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4909 break;
4910#endif
4911
4912 default:
4913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4914 __func__, key_mgmt);
4915 return -EINVAL;
4916
4917 }
4918 return 0;
4919}
4920
4921/*
4922 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4923 * This function is used to set the encryption type
4924 * (NONE/WEP40/WEP104/TKIP/CCMP).
4925 */
4926static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4927 u32 cipher,
4928 bool ucast
4929 )
4930{
4931 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4932 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4933 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4934
4935 ENTER();
4936
4937 if (!cipher)
4938 {
4939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4940 __func__, cipher);
4941 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4942 }
4943 else
4944 {
4945
4946 /*set encryption method*/
4947 switch (cipher)
4948 {
4949 case IW_AUTH_CIPHER_NONE:
4950 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4951 break;
4952
4953 case WLAN_CIPHER_SUITE_WEP40:
4954 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4955 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4956 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4957 else
4958 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4959 break;
4960
4961 case WLAN_CIPHER_SUITE_WEP104:
4962 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4963 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4964 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4965 else
4966 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4967 break;
4968
4969 case WLAN_CIPHER_SUITE_TKIP:
4970 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4971 break;
4972
4973 case WLAN_CIPHER_SUITE_CCMP:
4974 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4975 break;
4976#ifdef FEATURE_WLAN_WAPI
4977 case WLAN_CIPHER_SUITE_SMS4:
4978 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4979 break;
4980#endif
4981
4982#ifdef FEATURE_WLAN_CCX
4983 case WLAN_CIPHER_SUITE_KRK:
4984 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4985 break;
4986#endif
4987 default:
4988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4989 __func__, cipher);
4990 return -EOPNOTSUPP;
4991 }
4992 }
4993
4994 if (ucast)
4995 {
4996 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4997 __func__, encryptionType);
4998 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4999 pWextState->roamProfile.EncryptionType.numEntries = 1;
5000 pWextState->roamProfile.EncryptionType.encryptionType[0] =
5001 encryptionType;
5002 }
5003 else
5004 {
5005 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
5006 __func__, encryptionType);
5007 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5008 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5009 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5010 }
5011
5012 return 0;
5013}
5014
5015
5016/*
5017 * FUNCTION: wlan_hdd_cfg80211_set_ie
5018 * This function is used to parse WPA/RSN IE's.
5019 */
5020int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5021 u8 *ie,
5022 size_t ie_len
5023 )
5024{
5025 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5026 u8 *genie = ie;
5027 v_U16_t remLen = ie_len;
5028#ifdef FEATURE_WLAN_WAPI
5029 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5030 u16 *tmp;
5031 v_U16_t akmsuiteCount;
5032 int *akmlist;
5033#endif
5034 ENTER();
5035
5036 /* clear previous assocAddIE */
5037 pWextState->assocAddIE.length = 0;
5038 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5039
5040 while (remLen >= 2)
5041 {
5042 v_U16_t eLen = 0;
5043 v_U8_t elementId;
5044 elementId = *genie++;
5045 eLen = *genie++;
5046 remLen -= 2;
5047
5048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
5049 __func__, elementId, eLen);
5050
5051 switch ( elementId )
5052 {
5053 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005054 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 -07005055 {
5056 hddLog(VOS_TRACE_LEVEL_ERROR,
5057 "%s: Invalid WPA IE", __func__);
5058 return -EINVAL;
5059 }
5060 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
5061 {
5062 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5063 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
5064 __func__, eLen + 2);
5065
5066 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5067 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005068 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5069 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 VOS_ASSERT(0);
5071 return -ENOMEM;
5072 }
5073 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5074 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5075 pWextState->assocAddIE.length += eLen + 2;
5076
5077 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5078 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5079 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5080 }
5081 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5082 {
5083 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5084 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5085 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5086 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5087 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5088 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5090 P2P_OUI_TYPE_SIZE))
5091 /*Consider P2P IE, only for P2P Client */
5092 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5093 {
5094 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5095 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
5096 __func__, eLen + 2);
5097
5098 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5099 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005100 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5101 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 VOS_ASSERT(0);
5103 return -ENOMEM;
5104 }
5105 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5106 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5107 pWextState->assocAddIE.length += eLen + 2;
5108
5109 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5110 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5111 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005112#ifdef WLAN_FEATURE_WFD
5113 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5114 WFD_OUI_TYPE_SIZE))
5115 /*Consider WFD IE, only for P2P Client */
5116 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5117 {
5118 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5119 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
5120 __func__, eLen + 2);
5121
5122 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5123 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005124 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5125 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 VOS_ASSERT(0);
5127 return -ENOMEM;
5128 }
5129 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5130 // WPS IE + P2P IE + WFD IE
5131 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5132 pWextState->assocAddIE.length += eLen + 2;
5133
5134 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5135 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5136 }
5137#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005138 /* Appending HS 2.0 Indication Element in Assiciation Request */
5139 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005140 HS20_OUI_TYPE_SIZE)) )
5141 {
5142 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5143 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
5144 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005145
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005146 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5147 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005148 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5149 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005150 VOS_ASSERT(0);
5151 return -ENOMEM;
5152 }
5153 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5154 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005155
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005156 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5157 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5158 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005159
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 break;
5161 case DOT11F_EID_RSN:
5162 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5163 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5164 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5165 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5166 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5167 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005168 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5169 case DOT11F_EID_EXTCAP:
5170 {
5171 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5172 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5173 __func__, eLen + 2);
5174
5175 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5176 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005177 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5178 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005179 VOS_ASSERT(0);
5180 return -ENOMEM;
5181 }
5182 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5183 pWextState->assocAddIE.length += eLen + 2;
5184
5185 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5186 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5187 break;
5188 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005189#ifdef FEATURE_WLAN_WAPI
5190 case WLAN_EID_WAPI:
5191 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5192 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5193 pAdapter->wapi_info.nWapiMode);
5194 tmp = (u16 *)ie;
5195 tmp = tmp + 2; // Skip element Id and Len, Version
5196 akmsuiteCount = WPA_GET_LE16(tmp);
5197 tmp = tmp + 1;
5198 akmlist = (int *)(tmp);
5199 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5200 {
5201 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5202 }
5203 else
5204 {
5205 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5206 VOS_ASSERT(0);
5207 return -EINVAL;
5208 }
5209
5210 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5211 {
5212 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005213 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5215 }
5216 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5217 {
5218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005219 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005220 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5221 }
5222 break;
5223#endif
5224 default:
5225 hddLog (VOS_TRACE_LEVEL_ERROR,
5226 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005227 /* when Unknown IE is received we should break and continue
5228 * to the next IE in the buffer instead we were returning
5229 * so changing this to break */
5230 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005231 }
5232 genie += eLen;
5233 remLen -= eLen;
5234 }
5235 EXIT();
5236 return 0;
5237}
5238
5239/*
5240 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5241 * This function is used to initialize the security
5242 * parameters during connect operation.
5243 */
5244int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5245 struct cfg80211_connect_params *req
5246 )
5247{
5248 int status = 0;
5249 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5250 ENTER();
5251
5252 /*set wpa version*/
5253 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5254
5255 if (req->crypto.wpa_versions)
5256 {
5257 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5258 && ( (req->ie_len)
5259 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5260 // Make sure that it is including a WPA IE.
5261 /* Currently NL is putting WPA version 1 even for open,
5262 * since p2p ie is also put in same buffer.
5263 * */
5264 {
5265 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5266 }
5267 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5268 {
5269 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5270 }
5271 }
5272
5273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5274 pWextState->wpaVersion);
5275
5276 /*set authentication type*/
5277 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5278
5279 if (0 > status)
5280 {
5281 hddLog(VOS_TRACE_LEVEL_ERROR,
5282 "%s: failed to set authentication type ", __func__);
5283 return status;
5284 }
5285
5286 /*set key mgmt type*/
5287 if (req->crypto.n_akm_suites)
5288 {
5289 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5290 if (0 > status)
5291 {
5292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5293 __func__);
5294 return status;
5295 }
5296 }
5297
5298 /*set pairwise cipher type*/
5299 if (req->crypto.n_ciphers_pairwise)
5300 {
5301 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5302 req->crypto.ciphers_pairwise[0], true);
5303 if (0 > status)
5304 {
5305 hddLog(VOS_TRACE_LEVEL_ERROR,
5306 "%s: failed to set unicast cipher type", __func__);
5307 return status;
5308 }
5309 }
5310 else
5311 {
5312 /*Reset previous cipher suite to none*/
5313 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5314 if (0 > status)
5315 {
5316 hddLog(VOS_TRACE_LEVEL_ERROR,
5317 "%s: failed to set unicast cipher type", __func__);
5318 return status;
5319 }
5320 }
5321
5322 /*set group cipher type*/
5323 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5324 false);
5325
5326 if (0 > status)
5327 {
5328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5329 __func__);
5330 return status;
5331 }
5332
5333 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5334 if (req->ie_len)
5335 {
5336 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5337 if ( 0 > status)
5338 {
5339 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5340 __func__);
5341 return status;
5342 }
5343 }
5344
5345 /*incase of WEP set default key information*/
5346 if (req->key && req->key_len)
5347 {
5348 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5349 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5350 )
5351 {
5352 if ( IW_AUTH_KEY_MGMT_802_1X
5353 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5354 {
5355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5356 __func__);
5357 return -EOPNOTSUPP;
5358 }
5359 else
5360 {
5361 u8 key_len = req->key_len;
5362 u8 key_idx = req->key_idx;
5363
5364 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5365 && (CSR_MAX_NUM_KEY > key_idx)
5366 )
5367 {
5368 hddLog(VOS_TRACE_LEVEL_INFO,
5369 "%s: setting default wep key, key_idx = %hu key_len %hu",
5370 __func__, key_idx, key_len);
5371 vos_mem_copy(
5372 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5373 req->key, key_len);
5374 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5375 (u8)key_len;
5376 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5377 }
5378 }
5379 }
5380 }
5381
5382 return status;
5383}
5384
5385/*
5386 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5387 * This function is used to initialize the security
5388 * parameters during connect operation.
5389 */
5390static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5391 struct net_device *ndev,
5392 struct cfg80211_connect_params *req
5393 )
5394{
5395 int status = 0;
5396 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5397 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5398 hdd_context_t *pHddCtx = NULL;
5399
5400 ENTER();
5401
5402 hddLog(VOS_TRACE_LEVEL_INFO,
5403 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5404
5405 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5406 {
5407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5408 "%s:LOGP in Progress. Ignore!!!", __func__);
5409 return -EAGAIN;
5410 }
5411
5412#ifdef WLAN_BTAMP_FEATURE
5413 //Infra connect not supported when AMP traffic is on.
5414 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5415 {
5416 hddLog(VOS_TRACE_LEVEL_ERROR,
5417 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005418 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005419 }
5420#endif
5421 /*initialise security parameters*/
5422 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5423
5424 if ( 0 > status)
5425 {
5426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5427 __func__);
5428 return status;
5429 }
5430
5431 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005432 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5434 (vos_concurrent_sessions_running()))
5435 {
5436 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5437
5438 if (NULL != pVosContext)
5439 {
5440 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5441 if(NULL != pHddCtx)
5442 {
5443 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5444 }
5445 }
5446 }
5447
Mohit Khanna765234a2012-09-11 15:08:35 -07005448 if ( req->channel )
5449 {
5450 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5451 req->ssid_len, req->bssid,
5452 req->channel->hw_value);
5453 }
5454 else
5455 {
5456 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5457 req->ssid_len, req->bssid,
5458 0);
5459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005460
5461 if (0 > status)
5462 {
5463 //ReEnable BMPS if disabled
5464 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5465 (NULL != pHddCtx))
5466 {
5467 //ReEnable Bmps and Imps back
5468 hdd_enable_bmps_imps(pHddCtx);
5469 }
5470
5471 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5472 return status;
5473 }
5474 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5475 EXIT();
5476 return status;
5477}
5478
5479
5480/*
5481 * FUNCTION: wlan_hdd_cfg80211_disconnect
5482 * This function is used to issue a disconnect request to SME
5483 */
5484static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5485 struct net_device *dev,
5486 u16 reason
5487 )
5488{
5489 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5490 tCsrRoamProfile *pRoamProfile =
5491 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5492 int status = 0;
5493 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005494#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005495 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005496 tANI_U8 staIdx;
5497#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005498
5499 ENTER();
5500
5501 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5502 __func__,pAdapter->device_mode);
5503
5504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5505 __func__, reason);
5506
5507 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5508 {
5509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5510 "%s:LOGP in Progress. Ignore!!!",__func__);
5511 return -EAGAIN;
5512 }
5513 if (NULL != pRoamProfile)
5514 {
5515 /*issue disconnect request to SME, if station is in connected state*/
5516 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5517 {
5518 eCsrRoamDisconnectReason reasonCode =
5519 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5520 switch(reason)
5521 {
5522 case WLAN_REASON_MIC_FAILURE:
5523 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5524 break;
5525
5526 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5527 case WLAN_REASON_DISASSOC_AP_BUSY:
5528 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5529 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5530 break;
5531
5532 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5533 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5534 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5535 break;
5536
5537 case WLAN_REASON_DEAUTH_LEAVING:
5538 default:
5539 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5540 break;
5541 }
5542 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5543 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5544 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5545
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005546#ifdef FEATURE_WLAN_TDLS
5547 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005548 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005549 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005550 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5551 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005552 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005553 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005554 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005555 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
5556 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d %02x:%02x:%02x:%02x:%02x:%02x",
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005557 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005558 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005559 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005560 pAdapter->sessionId,
5561 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005562 }
5563 }
5564#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 /*issue disconnect*/
5566 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5567 pAdapter->sessionId, reasonCode);
5568
5569 if ( 0 != status)
5570 {
5571 hddLog(VOS_TRACE_LEVEL_ERROR,
5572 "%s csrRoamDisconnect failure, returned %d \n",
5573 __func__, (int)status );
5574 return -EINVAL;
5575 }
5576
5577 wait_for_completion_interruptible_timeout(
5578 &pAdapter->disconnect_comp_var,
5579 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5580
5581
5582 /*stop tx queues*/
5583 netif_tx_disable(dev);
5584 netif_carrier_off(dev);
5585 }
5586 }
5587 else
5588 {
5589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5590 }
5591
5592 return status;
5593}
5594
5595/*
5596 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5597 * This function is used to initialize the security
5598 * settings in IBSS mode.
5599 */
5600static int wlan_hdd_cfg80211_set_privacy_ibss(
5601 hdd_adapter_t *pAdapter,
5602 struct cfg80211_ibss_params *params
5603 )
5604{
5605 int status = 0;
5606 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5607 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5608 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5609
5610 ENTER();
5611
5612 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5613
5614 if (params->ie_len && ( NULL != params->ie) )
5615 {
5616 if (WLAN_EID_RSN == params->ie[0])
5617 {
5618 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5619 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5620 }
5621 else
5622 {
5623 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5624 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5625 }
5626 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5627
5628 if (0 > status)
5629 {
5630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5631 __func__);
5632 return status;
5633 }
5634 }
5635
5636 pWextState->roamProfile.AuthType.authType[0] =
5637 pHddStaCtx->conn_info.authType =
5638 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5639
5640 if (params->privacy)
5641 {
5642 /* Security enabled IBSS, At this time there is no information available
5643 * about the security paramters, so initialise the encryption type to
5644 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5645 * The correct security parameters will be updated later in
5646 * wlan_hdd_cfg80211_add_key */
5647 /* Hal expects encryption type to be set inorder
5648 *enable privacy bit in beacons */
5649
5650 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5651 }
5652
5653 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5654 pWextState->roamProfile.EncryptionType.numEntries = 1;
5655 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5656
5657 return status;
5658}
5659
5660/*
5661 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5662 * This function is used to create/join an IBSS
5663 */
5664static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5665 struct net_device *dev,
5666 struct cfg80211_ibss_params *params
5667 )
5668{
5669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5670 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5671 tCsrRoamProfile *pRoamProfile;
5672 int status;
5673 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5674
5675 ENTER();
5676
5677 hddLog(VOS_TRACE_LEVEL_INFO,
5678 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5679
5680 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5681 {
5682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5683 "%s:LOGP in Progress. Ignore!!!", __func__);
5684 return -EAGAIN;
5685 }
5686
5687 if (NULL == pWextState)
5688 {
5689 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5690 __func__);
5691 return -EIO;
5692 }
5693
5694 pRoamProfile = &pWextState->roamProfile;
5695
5696 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5697 {
5698 hddLog (VOS_TRACE_LEVEL_ERROR,
5699 "%s Interface type is not set to IBSS \n", __func__);
5700 return -EINVAL;
5701 }
5702
5703 /* Set Channel */
5704 if (NULL != params->channel)
5705 {
5706 u8 channelNum;
5707 if (IEEE80211_BAND_5GHZ == params->channel->band)
5708 {
5709 hddLog(VOS_TRACE_LEVEL_ERROR,
5710 "%s: IBSS join is called with unsupported band %d",
5711 __func__, params->channel->band);
5712 return -EOPNOTSUPP;
5713 }
5714
5715 /* Get channel number */
5716 channelNum =
5717 ieee80211_frequency_to_channel(params->channel->center_freq);
5718
5719 /*TODO: use macro*/
5720 if (14 >= channelNum)
5721 {
5722 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5723 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5724 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5725 int indx;
5726
5727 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5728 validChan, &numChans))
5729 {
5730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5731 __func__);
5732 return -EOPNOTSUPP;
5733 }
5734
5735 for (indx = 0; indx < numChans; indx++)
5736 {
5737 if (channelNum == validChan[indx])
5738 {
5739 break;
5740 }
5741 }
5742 if (indx >= numChans)
5743 {
5744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5745 __func__, channelNum);
5746 return -EINVAL;
5747 }
5748 /* Set the Operational Channel */
5749 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5750 channelNum);
5751 pRoamProfile->ChannelInfo.numOfChannels = 1;
5752 pHddStaCtx->conn_info.operationChannel = channelNum;
5753 pRoamProfile->ChannelInfo.ChannelList =
5754 &pHddStaCtx->conn_info.operationChannel;
5755 }
5756 else
5757 {
5758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5759 __func__, channelNum);
5760 return -EINVAL;
5761 }
5762 }
5763
5764 /* Initialize security parameters */
5765 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5766 if (status < 0)
5767 {
5768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5769 __func__);
5770 return status;
5771 }
5772
5773 /* Issue connect start */
5774 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005775 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005776
5777 if (0 > status)
5778 {
5779 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5780 return status;
5781 }
5782
5783 return 0;
5784}
5785
5786/*
5787 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5788 * This function is used to leave an IBSS
5789 */
5790static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5791 struct net_device *dev
5792 )
5793{
5794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5795 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5796 tCsrRoamProfile *pRoamProfile;
5797
5798 ENTER();
5799
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005800 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5801 {
5802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5803 "%s:LOGP in Progress. Ignore!!!", __func__);
5804 return -EAGAIN;
5805 }
5806
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5808 if (NULL == pWextState)
5809 {
5810 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5811 __func__);
5812 return -EIO;
5813 }
5814
5815 pRoamProfile = &pWextState->roamProfile;
5816
5817 /* Issue disconnect only if interface type is set to IBSS */
5818 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5819 {
5820 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5821 __func__);
5822 return -EINVAL;
5823 }
5824
5825 /* Issue Disconnect request */
5826 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5827 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5828 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5829
5830 return 0;
5831}
5832
5833/*
5834 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5835 * This function is used to set the phy parameters
5836 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5837 */
5838static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5839 u32 changed)
5840{
5841 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5842 tHalHandle hHal = pHddCtx->hHal;
5843
5844 ENTER();
5845
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005846 if ( pHddCtx->isLogpInProgress )
5847 {
5848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5849 "%s:LOGP in Progress. Ignore!!!", __func__);
5850 return -EAGAIN;
5851 }
5852
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5854 {
5855 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5856 WNI_CFG_RTS_THRESHOLD_STAMAX :
5857 wiphy->rts_threshold;
5858
5859 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5860 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5861 {
5862 hddLog(VOS_TRACE_LEVEL_ERROR,
5863 "%s: Invalid RTS Threshold value %hu",
5864 __func__, rts_threshold);
5865 return -EINVAL;
5866 }
5867
5868 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5869 rts_threshold, ccmCfgSetCallback,
5870 eANI_BOOLEAN_TRUE))
5871 {
5872 hddLog(VOS_TRACE_LEVEL_ERROR,
5873 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5874 __func__, rts_threshold);
5875 return -EIO;
5876 }
5877
5878 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5879 rts_threshold);
5880 }
5881
5882 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5883 {
5884 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5885 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5886 wiphy->frag_threshold;
5887
5888 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5889 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5890 {
5891 hddLog(VOS_TRACE_LEVEL_ERROR,
5892 "%s: Invalid frag_threshold value %hu", __func__,
5893 frag_threshold);
5894 return -EINVAL;
5895 }
5896
5897 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5898 frag_threshold, ccmCfgSetCallback,
5899 eANI_BOOLEAN_TRUE))
5900 {
5901 hddLog(VOS_TRACE_LEVEL_ERROR,
5902 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5903 __func__, frag_threshold);
5904 return -EIO;
5905 }
5906
5907 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5908 frag_threshold);
5909 }
5910
5911 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5912 || (changed & WIPHY_PARAM_RETRY_LONG))
5913 {
5914 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5915 wiphy->retry_short :
5916 wiphy->retry_long;
5917
5918 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5919 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5920 {
5921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5922 __func__, retry_value);
5923 return -EINVAL;
5924 }
5925
5926 if (changed & WIPHY_PARAM_RETRY_SHORT)
5927 {
5928 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5929 retry_value, ccmCfgSetCallback,
5930 eANI_BOOLEAN_TRUE))
5931 {
5932 hddLog(VOS_TRACE_LEVEL_ERROR,
5933 "%s: ccmCfgSetInt failed for long retry count %hu",
5934 __func__, retry_value);
5935 return -EIO;
5936 }
5937 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5938 __func__, retry_value);
5939 }
5940 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5941 {
5942 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5943 retry_value, ccmCfgSetCallback,
5944 eANI_BOOLEAN_TRUE))
5945 {
5946 hddLog(VOS_TRACE_LEVEL_ERROR,
5947 "%s: ccmCfgSetInt failed for short retry count %hu",
5948 __func__, retry_value);
5949 return -EIO;
5950 }
5951 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5952 __func__, retry_value);
5953 }
5954 }
5955
5956 return 0;
5957}
5958
5959/*
5960 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5961 * This function is used to set the txpower
5962 */
5963static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5964#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5965 enum tx_power_setting type,
5966#else
5967 enum nl80211_tx_power_setting type,
5968#endif
5969 int dbm)
5970{
5971 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5972 tHalHandle hHal = pHddCtx->hHal;
5973 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5974 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5975
5976 ENTER();
5977
5978 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5979 dbm, ccmCfgSetCallback,
5980 eANI_BOOLEAN_TRUE))
5981 {
5982 hddLog(VOS_TRACE_LEVEL_ERROR,
5983 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5984 return -EIO;
5985 }
5986
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005987 if ( pHddCtx->isLogpInProgress )
5988 {
5989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5990 "%s:LOGP in Progress. Ignore!!!", __func__);
5991 return -EAGAIN;
5992 }
5993
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5995 dbm);
5996
5997 switch(type)
5998 {
5999 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6000 /* Fall through */
6001 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6002 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6003 {
6004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6005 __func__);
6006 return -EIO;
6007 }
6008 break;
6009 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
6010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
6011 __func__);
6012 return -EOPNOTSUPP;
6013 break;
6014 default:
6015 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6016 __func__, type);
6017 return -EIO;
6018 }
6019
6020 return 0;
6021}
6022
6023/*
6024 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6025 * This function is used to read the txpower
6026 */
6027static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6028{
6029
6030 hdd_adapter_t *pAdapter;
6031 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6032
Jeff Johnsone7245742012-09-05 17:12:55 -07006033 ENTER();
6034
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 if (NULL == pHddCtx)
6036 {
6037 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6038 *dbm = 0;
6039 return -ENOENT;
6040 }
6041
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006042 if ( pHddCtx->isLogpInProgress )
6043 {
6044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6045 "%s:LOGP in Progress. Ignore!!!", __func__);
6046 return -EAGAIN;
6047 }
6048
Jeff Johnson295189b2012-06-20 16:38:30 -07006049 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6050 if (NULL == pAdapter)
6051 {
6052 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6053 return -ENOENT;
6054 }
6055
6056 wlan_hdd_get_classAstats(pAdapter);
6057 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6058
Jeff Johnsone7245742012-09-05 17:12:55 -07006059 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 return 0;
6061}
6062
6063static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6064 u8* mac, struct station_info *sinfo)
6065{
6066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6067 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6068 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6069 tANI_U8 rate_flags;
6070
6071 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6072 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006073
6074 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6075 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6076 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6077 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6078 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6079 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6080 tANI_U16 maxRate = 0;
6081 tANI_U16 myRate;
6082 tANI_U16 currentRate = 0;
6083 tANI_U8 maxSpeedMCS = 0;
6084 tANI_U8 maxMCSIdx = 0;
6085 tANI_U8 rateFlag = 1;
6086 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006087 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006088
Jeff Johnsone7245742012-09-05 17:12:55 -07006089 ENTER();
6090
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6092 (0 == ssidlen))
6093 {
6094 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6095 " Invalid ssidlen, %d", __func__, ssidlen);
6096 /*To keep GUI happy*/
6097 return 0;
6098 }
6099
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006100 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6101 {
6102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6103 "%s:LOGP in Progress. Ignore!!!", __func__);
6104 return -EAGAIN;
6105 }
6106
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6108 sinfo->filled |= STATION_INFO_SIGNAL;
6109
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006110 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006111 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6112
6113 //convert to the UI units of 100kbps
6114 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6115
6116#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006117 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 -07006118 sinfo->signal,
6119 pCfg->reportMaxLinkSpeed,
6120 myRate,
6121 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006122 (int) pCfg->linkSpeedRssiMid,
6123 (int) pCfg->linkSpeedRssiLow,
6124 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006125#endif //LINKSPEED_DEBUG_ENABLED
6126
6127 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6128 {
6129 // we do not want to necessarily report the current speed
6130 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6131 {
6132 // report the max possible speed
6133 rssidx = 0;
6134 }
6135 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6136 {
6137 // report the max possible speed with RSSI scaling
6138 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6139 {
6140 // report the max possible speed
6141 rssidx = 0;
6142 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006143 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 {
6145 // report middle speed
6146 rssidx = 1;
6147 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006148 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6149 {
6150 // report middle speed
6151 rssidx = 2;
6152 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 else
6154 {
6155 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006156 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006157 }
6158 }
6159 else
6160 {
6161 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6162 hddLog(VOS_TRACE_LEVEL_ERROR,
6163 "%s: Invalid value for reportMaxLinkSpeed: %u",
6164 __func__, pCfg->reportMaxLinkSpeed);
6165 rssidx = 0;
6166 }
6167
6168 maxRate = 0;
6169
6170 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306171 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6172 OperationalRates, &ORLeng))
6173 {
6174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6175 /*To keep GUI happy*/
6176 return 0;
6177 }
6178
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 for (i = 0; i < ORLeng; i++)
6180 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006181 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 {
6183 /* Validate Rate Set */
6184 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6185 {
6186 currentRate = supported_data_rate[j].supported_rate[rssidx];
6187 break;
6188 }
6189 }
6190 /* Update MAX rate */
6191 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6192 }
6193
6194 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306195 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6196 ExtendedRates, &ERLeng))
6197 {
6198 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6199 /*To keep GUI happy*/
6200 return 0;
6201 }
6202
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 for (i = 0; i < ERLeng; i++)
6204 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006205 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 {
6207 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6208 {
6209 currentRate = supported_data_rate[j].supported_rate[rssidx];
6210 break;
6211 }
6212 }
6213 /* Update MAX rate */
6214 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6215 }
6216
6217 /* Get MCS Rate Set -- but only if we are connected at MCS
6218 rates or if we are always reporting max speed or if we have
6219 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006220 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306222 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6223 MCSRates, &MCSLeng))
6224 {
6225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6226 /*To keep GUI happy*/
6227 return 0;
6228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 rateFlag = 0;
6230 if (rate_flags & eHAL_TX_RATE_HT40)
6231 {
6232 rateFlag |= 1;
6233 }
6234 if (rate_flags & eHAL_TX_RATE_SGI)
6235 {
6236 rateFlag |= 2;
6237 }
6238
6239 for (i = 0; i < MCSLeng; i++)
6240 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006241 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6242 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 {
6244 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6245 {
6246 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6247 break;
6248 }
6249 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006250 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 {
6252 maxRate = currentRate;
6253 maxSpeedMCS = 1;
6254 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6255 }
6256 }
6257 }
6258
6259 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006260 if (((maxRate < myRate) && (0 == rssidx)) ||
6261 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 {
6263 maxRate = myRate;
6264 if (rate_flags & eHAL_TX_RATE_LEGACY)
6265 {
6266 maxSpeedMCS = 0;
6267 }
6268 else
6269 {
6270 maxSpeedMCS = 1;
6271 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6272 }
6273 }
6274
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006275 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 {
6277 sinfo->txrate.legacy = maxRate;
6278#ifdef LINKSPEED_DEBUG_ENABLED
6279 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6280#endif //LINKSPEED_DEBUG_ENABLED
6281 }
6282 else
6283 {
6284 sinfo->txrate.mcs = maxMCSIdx;
6285 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6286 if (rate_flags & eHAL_TX_RATE_SGI)
6287 {
6288 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6289 }
6290 if (rate_flags & eHAL_TX_RATE_HT40)
6291 {
6292 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6293 }
6294#ifdef LINKSPEED_DEBUG_ENABLED
6295 pr_info("Reporting MCS rate %d flags %x\n",
6296 sinfo->txrate.mcs,
6297 sinfo->txrate.flags );
6298#endif //LINKSPEED_DEBUG_ENABLED
6299 }
6300 }
6301 else
6302 {
6303 // report current rate instead of max rate
6304
6305 if (rate_flags & eHAL_TX_RATE_LEGACY)
6306 {
6307 //provide to the UI in units of 100kbps
6308 sinfo->txrate.legacy = myRate;
6309#ifdef LINKSPEED_DEBUG_ENABLED
6310 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6311#endif //LINKSPEED_DEBUG_ENABLED
6312 }
6313 else
6314 {
6315 //must be MCS
6316 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6317 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6318 if (rate_flags & eHAL_TX_RATE_SGI)
6319 {
6320 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6321 }
6322 if (rate_flags & eHAL_TX_RATE_HT40)
6323 {
6324 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6325 }
6326#ifdef LINKSPEED_DEBUG_ENABLED
6327 pr_info("Reporting actual MCS rate %d flags %x\n",
6328 sinfo->txrate.mcs,
6329 sinfo->txrate.flags );
6330#endif //LINKSPEED_DEBUG_ENABLED
6331 }
6332 }
6333 sinfo->filled |= STATION_INFO_TX_BITRATE;
6334
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006335 sinfo->tx_packets =
6336 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6337 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6338 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6339 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6340
6341 sinfo->tx_retries =
6342 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6343 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6344 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6345 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6346
6347 sinfo->tx_failed =
6348 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6349 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6350 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6351 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6352
6353 sinfo->filled |=
6354 STATION_INFO_TX_PACKETS |
6355 STATION_INFO_TX_RETRIES |
6356 STATION_INFO_TX_FAILED;
6357
6358 EXIT();
6359 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006360}
6361
6362static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6363 struct net_device *dev, bool mode, v_SINT_t timeout)
6364{
6365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6366 VOS_STATUS vos_status;
6367
Jeff Johnsone7245742012-09-05 17:12:55 -07006368 ENTER();
6369
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 if (NULL == pAdapter)
6371 {
6372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6373 return -ENODEV;
6374 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006375 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6376 {
6377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6378 "%s:LOGP in Progress. Ignore!!!", __func__);
6379 return -EAGAIN;
6380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006381
6382 /**The get power cmd from the supplicant gets updated by the nl only
6383 *on successful execution of the function call
6384 *we are oppositely mapped w.r.t mode in the driver
6385 **/
6386 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6387
Jeff Johnsone7245742012-09-05 17:12:55 -07006388 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 if (VOS_STATUS_E_FAILURE == vos_status)
6390 {
6391 return -EINVAL;
6392 }
6393 return 0;
6394}
6395
6396
6397#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6398static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6399 struct net_device *netdev,
6400 u8 key_index)
6401{
Jeff Johnsone7245742012-09-05 17:12:55 -07006402 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 return 0;
6404}
6405#endif //LINUX_VERSION_CODE
6406
6407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6408static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6409 struct net_device *dev,
6410 struct ieee80211_txq_params *params)
6411{
Jeff Johnsone7245742012-09-05 17:12:55 -07006412 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 return 0;
6414}
6415#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6416static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6417 struct ieee80211_txq_params *params)
6418{
Jeff Johnsone7245742012-09-05 17:12:55 -07006419 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 return 0;
6421}
6422#endif //LINUX_VERSION_CODE
6423
6424static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6425 struct net_device *dev, u8 *mac)
6426{
6427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006428 VOS_STATUS vos_status;
6429 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006430
Jeff Johnsone7245742012-09-05 17:12:55 -07006431 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6433 {
6434 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6435 return -EINVAL;
6436 }
6437
6438 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6439 {
6440 hddLog( LOGE,
6441 "%s: Wlan Load/Unload is in progress", __func__);
6442 return -EBUSY;
6443 }
6444
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006445 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6446 {
6447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6448 "%s:LOGP in Progress. Ignore!!!", __func__);
6449 return -EAGAIN;
6450 }
6451
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 )
6455 {
6456 if( NULL == mac )
6457 {
6458 v_U16_t i;
6459 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6460 {
6461 if(pAdapter->aStaInfo[i].isUsed)
6462 {
6463 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6464 hddLog(VOS_TRACE_LEVEL_INFO,
6465 "%s: Delete STA with MAC::"
6466 "%02x:%02x:%02x:%02x:%02x:%02x",
6467 __func__,
6468 macAddr[0], macAddr[1], macAddr[2],
6469 macAddr[3], macAddr[4], macAddr[5]);
6470 hdd_softap_sta_deauth(pAdapter, macAddr);
6471 }
6472 }
6473 }
6474 else
6475 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006476
6477 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6478 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6479 {
6480 hddLog(VOS_TRACE_LEVEL_INFO,
6481 "%s: Skip this DEL STA as this is not used::"
6482 "%02x:%02x:%02x:%02x:%02x:%02x",
6483 __func__,
6484 mac[0], mac[1], mac[2],
6485 mac[3], mac[4], mac[5]);
6486 return -ENOENT;
6487 }
6488
6489 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6490 {
6491 hddLog(VOS_TRACE_LEVEL_INFO,
6492 "%s: Skip this DEL STA as deauth is in progress::"
6493 "%02x:%02x:%02x:%02x:%02x:%02x",
6494 __func__,
6495 mac[0], mac[1], mac[2],
6496 mac[3], mac[4], mac[5]);
6497 return -ENOENT;
6498 }
6499
6500 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6501
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 hddLog(VOS_TRACE_LEVEL_INFO,
6503 "%s: Delete STA with MAC::"
6504 "%02x:%02x:%02x:%02x:%02x:%02x",
6505 __func__,
6506 mac[0], mac[1], mac[2],
6507 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006508
6509 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6510 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6511 {
6512 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6513 hddLog(VOS_TRACE_LEVEL_INFO,
6514 "%s: STA removal failed for ::"
6515 "%02x:%02x:%02x:%02x:%02x:%02x",
6516 __func__,
6517 mac[0], mac[1], mac[2],
6518 mac[3], mac[4], mac[5]);
6519 return -ENOENT;
6520 }
6521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522 }
6523 }
6524
6525 EXIT();
6526
6527 return 0;
6528}
6529
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006530static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6531 struct net_device *dev, u8 *mac, struct station_parameters *params)
6532{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006533 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006534#ifdef FEATURE_WLAN_TDLS
6535 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006536 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006537 mask = params->sta_flags_mask;
6538
6539 set = params->sta_flags_set;
6540
Lee Hoonkic1262f22013-01-24 21:59:00 -08006541 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6542 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006543
6544 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6545 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006546 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006547 }
6548 }
6549#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006550 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006551}
6552
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006553
6554#ifdef FEATURE_WLAN_LFR
6555static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006556 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006557{
6558#define MAX_PMKSAIDS_IN_CACHE 8
6559 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006560 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006561 tANI_U32 j=0;
6562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6563 tHalHandle halHandle;
6564 eHalStatus result;
6565 tANI_U8 BSSIDMatched = 0;
6566
Jeff Johnsone7245742012-09-05 17:12:55 -07006567 ENTER();
6568
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006569 // Validate pAdapter
6570 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6571 {
6572 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6573 return -EINVAL;
6574 }
6575
6576 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6577 {
6578 hddLog( LOGE,
6579 "%s: Wlan Load/Unload is in progress", __func__);
6580 return -EBUSY;
6581 }
6582
6583 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6584 {
6585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6586 "%s:LOGP in Progress. Ignore!!!", __func__);
6587 return -EAGAIN;
6588 }
6589
6590 // Retrieve halHandle
6591 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6592
6593 for (j = 0; j < i; j++)
6594 {
6595 if(vos_mem_compare(PMKIDCache[j].BSSID,
6596 pmksa->bssid, WNI_CFG_BSSID_LEN))
6597 {
6598 /* BSSID matched previous entry. Overwrite it. */
6599 BSSIDMatched = 1;
6600 vos_mem_copy(PMKIDCache[j].BSSID,
6601 pmksa->bssid, WNI_CFG_BSSID_LEN);
6602 vos_mem_copy(PMKIDCache[j].PMKID,
6603 pmksa->pmkid,
6604 CSR_RSN_PMKID_SIZE);
6605 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006606 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006607 dump_bssid(pmksa->bssid);
6608 dump_pmkid(halHandle, pmksa->pmkid);
6609 break;
6610 }
6611 }
6612
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006613 /* Check we compared all entries,if then take the first slot now */
6614 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6615
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006616 if (!BSSIDMatched)
6617 {
6618 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6619 vos_mem_copy(PMKIDCache[i].BSSID,
6620 pmksa->bssid, ETHER_ADDR_LEN);
6621 vos_mem_copy(PMKIDCache[i].PMKID,
6622 pmksa->pmkid,
6623 CSR_RSN_PMKID_SIZE);
6624 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006625 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006626 dump_bssid(pmksa->bssid);
6627 dump_pmkid(halHandle, pmksa->pmkid);
6628 // Increment the HDD Local Cache index
6629 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6630 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6631 }
6632
6633
6634 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6635 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006636 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006637 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006638 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006639 // Finally set the PMKSA ID Cache in CSR
6640 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6641 PMKIDCache,
6642 i );
6643 return 0;
6644}
6645
6646
6647static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006648 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006649{
Jeff Johnsone7245742012-09-05 17:12:55 -07006650 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006651 // TODO: Implement this later.
6652 return 0;
6653}
6654
6655static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6656{
Jeff Johnsone7245742012-09-05 17:12:55 -07006657 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006658 // TODO: Implement this later.
6659 return 0;
6660}
6661#endif
6662
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006663#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6664static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6665 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6666{
6667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6668 hdd_station_ctx_t *pHddStaCtx;
6669
6670 if (NULL == pAdapter)
6671 {
6672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6673 return -ENODEV;
6674 }
6675
6676 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6677
6678 // Added for debug on reception of Re-assoc Req.
6679 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6680 {
6681 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6682 ftie->ie_len);
6683 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6684 }
6685
6686#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6687 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6688 ftie->ie_len);
6689#endif
6690
6691 // Pass the received FT IEs to SME
6692 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6693 ftie->ie_len);
6694 return 0;
6695}
6696#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006697
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006698#ifdef FEATURE_WLAN_TDLS
6699static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6700 u8 *peer, u8 action_code, u8 dialog_token,
6701 u16 status_code, const u8 *buf, size_t len)
6702{
6703
6704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6705 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006706 u8 peerMac[6];
6707 VOS_STATUS status;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006708 int ret = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006709 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006710
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006711 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006712 {
6713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6714 "Invalid arguments");
6715 return -EINVAL;
6716 }
6717
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006718 if (pHddCtx->isLogpInProgress)
6719 {
6720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6721 "%s:LOGP in Progress. Ignore!!!", __func__);
6722 return -EBUSY;
6723 }
6724
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006725 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006726 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6727 {
6728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6729 "TDLS Disabled in INI OR not enabled in FW.\
6730 Cannot process TDLS commands \n");
6731 return -ENOTSUPP;
6732 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006733
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006734 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
6735 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006736 if (wlan_hdd_tdls_is_progress(pAdapter, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006737 {
6738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6739 "%s: TDLS setup is ongoing. Request declined.", __func__);
6740 return -EPERM;
6741 }
6742 }
6743
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006744 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
6745 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08006746 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006747 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006748 {
6749 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6750 we return error code at 'add_station()'. Hence we have this
6751 check again in addtion to add_station().
6752 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006753 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006754 {
6755 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6756 "%s: TDLS Max peer already connected. Request declined. \n",
6757 __func__);
6758 return -EPERM;
6759 }
6760 else
6761 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006762 /* maximum reached. tweak to send error code to peer and return
6763 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006764 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6765 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6766 "%s: TDLS Max peer already connected send response status %d \n",
6767 __func__,status_code);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006768 ret = -EPERM;
6769 /* fall through to send setup resp with failure status
6770 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006771 }
6772 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006773 else
6774 {
6775 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006776 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006777 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
6778 {
6779 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6780 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
6781 __func__, peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6782 return -EPERM;
6783 }
6784 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006785 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006786 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006787
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006788#ifdef WLAN_FEATURE_TDLS_DEBUG
6789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6790 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6791 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6792 action_code, dialog_token, status_code, len);
6793#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006794
Hoonki Leea34dd892013-02-05 22:56:02 -08006795 /*Except teardown responder will not be used so just make 0*/
6796 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006797 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08006798 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006799 responder = wlan_hdd_tdls_get_responder(pAdapter, peerMac);
6800 if(-1 == responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08006801 {
6802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6803 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6804 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6805 dialog_token, status_code, len);
6806 return -EPERM;
6807 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006808 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006809
Pervinder Singhb4638422013-03-04 22:51:36 -08006810 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006811 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006812 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_CONNECTING);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006813
6814 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
6815
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006816 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006817 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006818
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006819 if (VOS_STATUS_SUCCESS != status)
6820 {
6821 if(ret == 0 && /* if failure, don't need to set the progress bit */
6822 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006823 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006824
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6826 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006827 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006828 }
6829
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006830 /* not block discovery request, as it is called from timer callback */
6831 if (SIR_MAC_TDLS_DIS_REQ != action_code)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006832 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006833 long rc;
6834
6835 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006836 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006837
Pervinder Singhb4638422013-03-04 22:51:36 -08006838 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006839 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006840 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006841 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006842 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006843
6844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pervinder Singhb4638422013-03-04 22:51:36 -08006845 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
6846 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006847 return -EPERM;
6848 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006849 }
6850
6851 if (ret)
6852 return ret;
6853
Hoonki Leea34dd892013-02-05 22:56:02 -08006854 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6855 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006856 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006857 }
6858 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6859 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006860 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006861 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006862
6863 return 0;
6864}
6865
6866static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6867 u8 *peer, enum nl80211_tdls_operation oper)
6868{
6869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6870 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006871#ifdef WLAN_FEATURE_TDLS_DEBUG
6872 const char *tdls_oper_str[]= {
6873 "NL80211_TDLS_DISCOVERY_REQ",
6874 "NL80211_TDLS_SETUP",
6875 "NL80211_TDLS_TEARDOWN",
6876 "NL80211_TDLS_ENABLE_LINK",
6877 "NL80211_TDLS_DISABLE_LINK",
6878 "NL80211_TDLS_UNKONW_OPER"};
6879#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006880
6881 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6882 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006884 "Invalid arguments");
6885 return -EINVAL;
6886 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006887
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006888 if (pHddCtx->isLogpInProgress)
6889 {
6890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6891 "%s:LOGP in Progress. Ignore!!!", __func__);
6892 return -EBUSY;
6893 }
6894
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006895#ifdef WLAN_FEATURE_TDLS_DEBUG
6896 if((int)oper > 4)
6897 oper = 5;
6898
6899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6900 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6901 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6902 tdls_oper_str[(int)oper]);
6903#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006904
6905 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006906 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006907 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006909 "TDLS Disabled in INI OR not enabled in FW.\
6910 Cannot process TDLS commands \n");
6911 return -ENOTSUPP;
6912 }
6913
6914 switch (oper) {
6915 case NL80211_TDLS_ENABLE_LINK:
6916 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006917 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006918 VOS_STATUS status;
6919
6920 if (peer) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006921 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006922
6923 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006924 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006925 __func__, peer[0], peer[1],
6926 peer[2], peer[3],
6927 peer[4], peer[5] );
6928
Hoonki Lee387663d2013-02-05 18:08:43 -08006929 if ( NULL == pTdlsPeer ) {
6930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6931 __func__, peer[0], peer[1],
6932 peer[2], peer[3],
6933 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006934 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006935 }
6936
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006937 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
6938 {
6939 /* start TDLS client registration with TL */
6940 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006941 wlan_hdd_tdls_increment_peer_count(pAdapter);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006942 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006943 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006944 }
Chilam NG571c65a2013-01-19 12:27:36 +05306945
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006946 } else {
6947 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6948 }
6949 }
6950 break;
6951 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006952 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006953 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006954
6955 if(NULL != curr_peer)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006956 {
6957 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6958 pAdapter->sessionId, peer );
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006959 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08006960 }
6961 else
6962 {
6963 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6964 "%s: TDLS Peer Station doesn't exist \n",__func__);
6965 }
6966 return 0;
6967 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006968 case NL80211_TDLS_TEARDOWN:
6969 case NL80211_TDLS_SETUP:
6970 case NL80211_TDLS_DISCOVERY_REQ:
6971 /* We don't support in-driver setup/teardown/discovery */
6972 return -ENOTSUPP;
6973 default:
6974 return -ENOTSUPP;
6975 }
6976 return 0;
6977}
Chilam NG571c65a2013-01-19 12:27:36 +05306978
6979int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6980 struct net_device *dev, u8 *peer)
6981{
6982 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6983 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6984
6985 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6986 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6987}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006988#endif
6989
Jeff Johnson295189b2012-06-20 16:38:30 -07006990/* cfg80211_ops */
6991static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6992{
6993 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6994 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6995 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6996 .change_station = wlan_hdd_change_station,
6997#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6998 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6999 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7000 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007001#else
7002 .start_ap = wlan_hdd_cfg80211_start_ap,
7003 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7004 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007005#endif
7006 .change_bss = wlan_hdd_cfg80211_change_bss,
7007 .add_key = wlan_hdd_cfg80211_add_key,
7008 .get_key = wlan_hdd_cfg80211_get_key,
7009 .del_key = wlan_hdd_cfg80211_del_key,
7010 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007011#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007012 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 .scan = wlan_hdd_cfg80211_scan,
7015 .connect = wlan_hdd_cfg80211_connect,
7016 .disconnect = wlan_hdd_cfg80211_disconnect,
7017 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7018 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7019 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7020 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7021 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7023 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7024 .mgmt_tx = wlan_hdd_action,
7025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7026 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7027 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7028 .set_txq_params = wlan_hdd_set_txq_params,
7029#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 .get_station = wlan_hdd_cfg80211_get_station,
7031 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7032 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007033 .add_station = wlan_hdd_cfg80211_add_station,
7034#ifdef FEATURE_WLAN_LFR
7035 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7036 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7037 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7038#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007039#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7040 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7041#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007042#ifdef FEATURE_WLAN_TDLS
7043 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7044 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7045#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007046};
7047