blob: a898b004b09e278959efa18ec2e8991468f8cd66 [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 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2728 "%s: " MAC_ADDRESS_STR
2729 " TDLS setup is ongoing. Request declined.",
2730 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002731 return -EPERM;
2732 }
2733
2734 /* first to check if we reached to maximum supported TDLS peer.
2735 TODO: for now, return -EPERM looks working fine,
2736 but need to check if any other errno fit into this category.*/
2737 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2738 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2740 "%s: " MAC_ADDRESS_STR
2741 " TDLS Max peer already connected. Request declined.",
2742 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002743 return -EPERM;
2744 }
2745 else
2746 {
2747 hddTdlsPeer_t *pTdlsPeer;
2748 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2749 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
2750 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2752 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2753 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002754 return -EPERM;
2755 }
2756 }
2757
2758 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
2759
2760 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2761
2762 if (!update)
2763 {
2764 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2765 pAdapter->sessionId, mac);
2766 }
2767 else
2768 {
2769 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2770 pAdapter->sessionId, mac, StaParams);
2771 }
2772
2773 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2774 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2775
2776 if (!status)
2777 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002779 "%s: timeout waiting for tdls add station indication",
2780 __func__);
2781 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2782 return -EPERM;
2783 }
2784 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2785 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002787 "%s: Add Station is unsucessful", __func__);
2788 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2789 return -EPERM;
2790 }
2791
2792 return 0;
2793}
2794#endif
2795
Jeff Johnson295189b2012-06-20 16:38:30 -07002796static int wlan_hdd_change_station(struct wiphy *wiphy,
2797 struct net_device *dev,
2798 u8 *mac,
2799 struct station_parameters *params)
2800{
2801 VOS_STATUS status = VOS_STATUS_SUCCESS;
2802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2803 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002804#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002805 tCsrStaParams StaParams = {0};
2806 u32 set;
2807 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002808#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002809 ENTER();
2810
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002811 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2812 {
2813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2814 "%s:LOGP in Progress. Ignore!!!", __func__);
2815 return -EAGAIN;
2816 }
2817
Jeff Johnson295189b2012-06-20 16:38:30 -07002818 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2819
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002820#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002821 StaParams.capability = params->capability;
2822 StaParams.uapsd_queues = params->uapsd_queues;
2823 StaParams.max_sp = params->max_sp;
2824
2825 if (0 != params->ext_capab_len)
2826 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2827 sizeof(StaParams.extn_capability));
2828
2829 if (NULL != params->ht_capa)
2830 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
2831
2832 StaParams.supported_rates_len = params->supported_rates_len;
2833
2834 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2835 * The supported_rates array , for all the structures propogating till Add Sta
2836 * to the firmware has to be modified , if the supplicant (ieee80211) is
2837 * modified to send more rates.
2838 */
2839
2840 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2841 */
2842 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2843 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2844
2845 if (0 != StaParams.supported_rates_len) {
2846 int i = 0;
2847 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2848 StaParams.supported_rates_len);
2849 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2850 "Supported Rates with Length %d", StaParams.supported_rates_len);
2851 for (i=0; i < StaParams.supported_rates_len; i++)
2852 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2853 "[%d]: %0x", i, StaParams.supported_rates[i]);
2854 }
2855
2856 if (NULL != params->vht_capa)
2857 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
2858
2859 set = params->sta_flags_set;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002860#endif
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002861
2862 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2863 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002864 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002865 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002866 {
2867 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2868 WLANTL_STA_AUTHENTICATED);
2869
2870 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002871 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002872 return -EINVAL;
2873 }
2874 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002875#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002876 else if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ) {
2877 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2878 if (0 != params->ext_capab_len ) {
2879 /*Define A Macro : TODO Sunil*/
2880 if ((1<<4) & StaParams.extn_capability[3]) {
2881 isBufSta = 1;
2882 }
2883 }
2884 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2885 "%s: TDLS Peer Parameters.", __func__);
2886 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2887 "uapsd_queues: %0x\n", params->uapsd_queues);
2888 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2889 "max_sp: %0x\n", params->max_sp);
2890 if (params->ht_capa) {
2891 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2892 "ht_capa->cap_info: %0x\n", params->ht_capa->cap_info);
2893 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2894 "ht_capa->ampdu_params_info: %0x\n",
2895 params->ht_capa->ampdu_params_info);
2896 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2897 "ht_capa->extended_capabilities: %0x\n",
2898 params->ht_capa->extended_ht_cap_info);
2899 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2900 "ht_capa->tx_BF_cap_info: %0x\n",
2901 params->ht_capa->tx_BF_cap_info);
2902 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2903 "ht_capa->antenna_selection_info: %0x\n",
2904 params->ht_capa->antenna_selection_info);
2905 }
2906 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2907 "params->capability: %0x\n",params->capability);
2908 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2909 "params->ext_capab_len: %0x\n",params->ext_capab_len);
2910 if (0 != params->ext_capab_len )
2911 {
2912 int i =0;
2913 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2914 "Extended capabilities:");
2915 for (i=0; i < params->ext_capab_len; i++)
2916 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2917 "[%d]: %0x", i, params->ext_capab[i]);
2918 }
2919 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
2920 // params->max_sp, isBufSta);
2921 if (VOS_STATUS_SUCCESS != status) {
2922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2923 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
2924 return -EINVAL;
2925 }
2926 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2927 "ht_capa->cap_info: %0x\n", StaParams.HTCap.capInfo);
2928 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
2929
2930 if (VOS_STATUS_SUCCESS != status) {
2931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2932 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
2933 return -EINVAL;
2934 }
2935 }
2936 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002937#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002938
Jeff Johnsone7245742012-09-05 17:12:55 -07002939 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002940 return status;
2941}
2942
2943/*
2944 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2945 * This function is used to get peer station index in IBSS mode
2946 */
2947static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2948{
2949 u8 idx = 0;
2950 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2951 ENTER();
2952 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2953 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2954 {
2955 if ( (0 !=
2956 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2957 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2958 temp, VOS_MAC_ADDR_SIZE)
2959 )
2960 {
2961 return idx;
2962 }
2963 }
2964 return idx;
2965}
2966
2967
2968/*
2969 * FUNCTION: wlan_hdd_cfg80211_add_key
2970 * This function is used to initialize the key information
2971 */
2972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2973static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2974 struct net_device *ndev,
2975 u8 key_index, bool pairwise,
2976 const u8 *mac_addr,
2977 struct key_params *params
2978 )
2979#else
2980static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2981 struct net_device *ndev,
2982 u8 key_index, const u8 *mac_addr,
2983 struct key_params *params
2984 )
2985#endif
2986{
2987 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2988 tCsrRoamSetKey setKey;
2989 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2990 int status = 0;
2991 v_U32_t roamId= 0xFF;
2992 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2993 hdd_hostapd_state_t *pHostapdState;
2994 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002995 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002996
2997 ENTER();
2998
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002999 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3000 {
3001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3002 "%s:LOGP in Progress. Ignore!!!", __func__);
3003 return -EAGAIN;
3004 }
3005
Jeff Johnson295189b2012-06-20 16:38:30 -07003006 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3007 __func__,pAdapter->device_mode);
3008
3009 if (CSR_MAX_NUM_KEY <= key_index)
3010 {
3011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3012 key_index);
3013
3014 return -EINVAL;
3015 }
3016
3017 hddLog(VOS_TRACE_LEVEL_INFO,
3018 "%s: called with key index = %d & key length %d",
3019 __func__, key_index, params->key_len);
3020
3021 /*extract key idx, key len and key*/
3022 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3023 setKey.keyId = key_index;
3024 setKey.keyLength = params->key_len;
3025 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3026
3027 switch (params->cipher)
3028 {
3029 case WLAN_CIPHER_SUITE_WEP40:
3030 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3031 break;
3032
3033 case WLAN_CIPHER_SUITE_WEP104:
3034 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3035 break;
3036
3037 case WLAN_CIPHER_SUITE_TKIP:
3038 {
3039 u8 *pKey = &setKey.Key[0];
3040 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3041
3042 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3043
3044 /*Supplicant sends the 32bytes key in this order
3045
3046 |--------------|----------|----------|
3047 | Tk1 |TX-MIC | RX Mic |
3048 |--------------|----------|----------|
3049 <---16bytes---><--8bytes--><--8bytes-->
3050
3051 */
3052 /*Sme expects the 32 bytes key to be in the below order
3053
3054 |--------------|----------|----------|
3055 | Tk1 |RX-MIC | TX Mic |
3056 |--------------|----------|----------|
3057 <---16bytes---><--8bytes--><--8bytes-->
3058 */
3059 /* Copy the Temporal Key 1 (TK1) */
3060 vos_mem_copy(pKey, params->key,16);
3061
3062 /*Copy the rx mic first*/
3063 vos_mem_copy(&pKey[16],&params->key[24],8);
3064
3065 /*Copy the tx mic */
3066 vos_mem_copy(&pKey[24],&params->key[16],8);
3067
3068
3069 break;
3070 }
3071
3072 case WLAN_CIPHER_SUITE_CCMP:
3073 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3074 break;
3075
3076#ifdef FEATURE_WLAN_WAPI
3077 case WLAN_CIPHER_SUITE_SMS4:
3078 {
3079 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3080 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3081 params->key, params->key_len);
3082 return 0;
3083 }
3084#endif
3085#ifdef FEATURE_WLAN_CCX
3086 case WLAN_CIPHER_SUITE_KRK:
3087 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3088 break;
3089#endif
3090 default:
3091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3092 __func__, params->cipher);
3093 return -EOPNOTSUPP;
3094 }
3095
3096 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3097 __func__, setKey.encType);
3098
3099
3100
3101 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 )
3104 {
3105
3106
3107 if (
3108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3109 (!pairwise)
3110#else
3111 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3112#endif
3113 )
3114 {
3115 /* set group key*/
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003117 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003118 __func__, __LINE__);
3119 setKey.keyDirection = eSIR_RX_ONLY;
3120 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3121 }
3122 else
3123 {
3124 /* set pairwise key*/
3125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3126 "%s- %d: setting pairwise key",
3127 __func__, __LINE__);
3128 setKey.keyDirection = eSIR_TX_RX;
3129 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3130 }
3131
3132 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3133 if( pHostapdState->bssState == BSS_START )
3134 {
3135 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3136
3137 if ( status != eHAL_STATUS_SUCCESS )
3138 {
3139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3140 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3141 __LINE__, status );
3142 }
3143 }
3144
3145 /* Saving WEP keys */
3146 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3147 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3148 {
3149 //Save the wep key in ap context. Issue setkey after the BSS is started.
3150 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3151 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3152 }
3153 else
3154 {
3155 //Save the key in ap context. Issue setkey after the BSS is started.
3156 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3157 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3158 }
3159 }
3160 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003161 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003162 )
3163 {
3164 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3165 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3166
3167 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3168
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003169 pWextState->roamProfile.Keys.defaultIndex = key_index;
3170
3171
Jeff Johnson295189b2012-06-20 16:38:30 -07003172 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3173 params->key, params->key_len);
3174
3175 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3176
3177 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3178 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3179 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3180 )
3181 &&
3182 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3183 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3184 )
3185 )
3186 {
3187 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3188 * interface, copy bssid for pairwise key and group macaddr for
3189 * group key initialization*/
3190
3191 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3192
3193 pWextState->roamProfile.negotiatedUCEncryptionType =
3194 pHddStaCtx->conn_info.ucEncryptionType =
3195 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3196 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3197 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3198
3199
3200 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3201 "%s: Negotiated encryption type %d", __func__,
3202 pWextState->roamProfile.negotiatedUCEncryptionType);
3203
3204 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3205 &pWextState->roamProfile, true);
3206 setKey.keyLength = 0;
3207 setKey.keyDirection = eSIR_TX_RX;
3208
3209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3210 if (pairwise)
3211 {
3212#endif
3213 if (mac_addr)
3214 {
3215 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3216 }
3217 else
3218 {
3219 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3220 * and peerMacAddress in case of IBSS*/
3221 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3222 {
3223 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3224 if (HDD_MAX_NUM_IBSS_STA != staidx)
3225 {
3226 vos_mem_copy(setKey.peerMac,
3227 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3228 WNI_CFG_BSSID_LEN);
3229
3230 }
3231 else
3232 {
3233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3234 __func__);
3235 return -EOPNOTSUPP;
3236 }
3237 }
3238 else
3239 {
3240 vos_mem_copy(setKey.peerMac,
3241 &pHddStaCtx->conn_info.bssId[0],
3242 WNI_CFG_BSSID_LEN);
3243 }
3244 }
3245#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3246 }
3247 else
3248 {
3249 /* set group key*/
3250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3251 "%s- %d: setting Group key",
3252 __func__, __LINE__);
3253 setKey.keyDirection = eSIR_RX_ONLY;
3254 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3255 }
3256#endif
3257 }
3258 else if (
3259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3260 (!pairwise)
3261#else
3262 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3263#endif
3264 )
3265 {
3266 /* set group key*/
3267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3268 "%s- %d: setting Group key",
3269 __func__, __LINE__);
3270 setKey.keyDirection = eSIR_RX_ONLY;
3271 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3272 }
3273 else
3274 {
3275 /* set pairwise key*/
3276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3277 "%s- %d: setting pairwise key",
3278 __func__, __LINE__);
3279 setKey.keyDirection = eSIR_TX_RX;
3280 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3281 }
3282
3283 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3284 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3285 __func__, setKey.peerMac[0], setKey.peerMac[1],
3286 setKey.peerMac[2], setKey.peerMac[3],
3287 setKey.peerMac[4], setKey.peerMac[5],
3288 setKey.keyDirection);
3289
3290 vos_status = wlan_hdd_check_ula_done(pAdapter);
3291
3292 if ( vos_status != VOS_STATUS_SUCCESS )
3293 {
3294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3295 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3296 __LINE__, vos_status );
3297
3298 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3299
3300 return -EINVAL;
3301
3302 }
3303
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003304#ifdef WLAN_FEATURE_VOWIFI_11R
3305 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3306 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003307 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303308 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003309 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303310 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003311 }
3312#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003313
3314 /* issue set key request to SME*/
3315 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3316 pAdapter->sessionId, &setKey, &roamId );
3317
3318 if ( 0 != status )
3319 {
3320 hddLog(VOS_TRACE_LEVEL_ERROR,
3321 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3322 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3323 return -EINVAL;
3324 }
3325
3326
3327 /* in case of IBSS as there was no information available about WEP keys during
3328 * IBSS join, group key intialized with NULL key, so re-initialize group key
3329 * with correct value*/
3330 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3331 !( ( IW_AUTH_KEY_MGMT_802_1X
3332 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3333 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3334 )
3335 &&
3336 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3337 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3338 )
3339 )
3340 {
3341 setKey.keyDirection = eSIR_RX_ONLY;
3342 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3343
3344 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3345 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3346 __func__, setKey.peerMac[0], setKey.peerMac[1],
3347 setKey.peerMac[2], setKey.peerMac[3],
3348 setKey.peerMac[4], setKey.peerMac[5],
3349 setKey.keyDirection);
3350
3351 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3352 pAdapter->sessionId, &setKey, &roamId );
3353
3354 if ( 0 != status )
3355 {
3356 hddLog(VOS_TRACE_LEVEL_ERROR,
3357 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3358 __func__, status);
3359 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3360 return -EINVAL;
3361 }
3362 }
3363 }
3364
3365 return 0;
3366}
3367
3368/*
3369 * FUNCTION: wlan_hdd_cfg80211_get_key
3370 * This function is used to get the key information
3371 */
3372#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3373static int wlan_hdd_cfg80211_get_key(
3374 struct wiphy *wiphy,
3375 struct net_device *ndev,
3376 u8 key_index, bool pairwise,
3377 const u8 *mac_addr, void *cookie,
3378 void (*callback)(void *cookie, struct key_params*)
3379 )
3380#else
3381static int wlan_hdd_cfg80211_get_key(
3382 struct wiphy *wiphy,
3383 struct net_device *ndev,
3384 u8 key_index, const u8 *mac_addr, void *cookie,
3385 void (*callback)(void *cookie, struct key_params*)
3386 )
3387#endif
3388{
3389 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3390 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3391 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3392 struct key_params params;
3393
3394 ENTER();
3395
3396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3397 __func__,pAdapter->device_mode);
3398
3399 memset(&params, 0, sizeof(params));
3400
3401 if (CSR_MAX_NUM_KEY <= key_index)
3402 {
3403 return -EINVAL;
3404 }
3405
3406 switch(pRoamProfile->EncryptionType.encryptionType[0])
3407 {
3408 case eCSR_ENCRYPT_TYPE_NONE:
3409 params.cipher = IW_AUTH_CIPHER_NONE;
3410 break;
3411
3412 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3413 case eCSR_ENCRYPT_TYPE_WEP40:
3414 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3415 break;
3416
3417 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3418 case eCSR_ENCRYPT_TYPE_WEP104:
3419 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3420 break;
3421
3422 case eCSR_ENCRYPT_TYPE_TKIP:
3423 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3424 break;
3425
3426 case eCSR_ENCRYPT_TYPE_AES:
3427 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3428 break;
3429
3430 default:
3431 params.cipher = IW_AUTH_CIPHER_NONE;
3432 break;
3433 }
3434
3435 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3436 params.seq_len = 0;
3437 params.seq = NULL;
3438 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3439 callback(cookie, &params);
3440 return 0;
3441}
3442
3443/*
3444 * FUNCTION: wlan_hdd_cfg80211_del_key
3445 * This function is used to delete the key information
3446 */
3447#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3448static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3449 struct net_device *ndev,
3450 u8 key_index,
3451 bool pairwise,
3452 const u8 *mac_addr
3453 )
3454#else
3455static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3456 struct net_device *ndev,
3457 u8 key_index,
3458 const u8 *mac_addr
3459 )
3460#endif
3461{
3462 int status = 0;
3463
3464 //This code needs to be revisited. There is sme_removeKey API, we should
3465 //plan to use that. After the change to use correct index in setkey,
3466 //it is observed that this is invalidating peer
3467 //key index whenever re-key is done. This is affecting data link.
3468 //It should be ok to ignore del_key.
3469#if 0
3470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3471 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3472 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3473 tCsrRoamSetKey setKey;
3474 v_U32_t roamId= 0xFF;
3475
3476 ENTER();
3477
3478 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3479 __func__,pAdapter->device_mode);
3480
3481 if (CSR_MAX_NUM_KEY <= key_index)
3482 {
3483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3484 key_index);
3485
3486 return -EINVAL;
3487 }
3488
3489 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3490 setKey.keyId = key_index;
3491
3492 if (mac_addr)
3493 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3494 else
3495 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3496
3497 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3498
3499 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003500 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003501 )
3502 {
3503
3504 hdd_hostapd_state_t *pHostapdState =
3505 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3506 if( pHostapdState->bssState == BSS_START)
3507 {
3508 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3509
3510 if ( status != eHAL_STATUS_SUCCESS )
3511 {
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3513 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3514 __LINE__, status );
3515 }
3516 }
3517 }
3518 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003519 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003520 )
3521 {
3522 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3523
3524 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3525
3526 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3527 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3528 __func__, setKey.peerMac[0], setKey.peerMac[1],
3529 setKey.peerMac[2], setKey.peerMac[3],
3530 setKey.peerMac[4], setKey.peerMac[5]);
3531 if(pAdapter->sessionCtx.station.conn_info.connState ==
3532 eConnectionState_Associated)
3533 {
3534 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3535 pAdapter->sessionId, &setKey, &roamId );
3536
3537 if ( 0 != status )
3538 {
3539 hddLog(VOS_TRACE_LEVEL_ERROR,
3540 "%s: sme_RoamSetKey failure, returned %d",
3541 __func__, status);
3542 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3543 return -EINVAL;
3544 }
3545 }
3546 }
3547#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003548 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003549 return status;
3550}
3551
3552/*
3553 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3554 * This function is used to set the default tx key index
3555 */
3556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3557static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3558 struct net_device *ndev,
3559 u8 key_index,
3560 bool unicast, bool multicast)
3561#else
3562static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3563 struct net_device *ndev,
3564 u8 key_index)
3565#endif
3566{
3567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3568 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3569 int status = 0;
3570 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3571
3572 ENTER();
3573
3574 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3575 __func__,pAdapter->device_mode, key_index);
3576
3577 if (CSR_MAX_NUM_KEY <= key_index)
3578 {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3580 key_index);
3581
3582 return -EINVAL;
3583 }
3584
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003585 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3586 {
3587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3588 "%s:LOGP in Progress. Ignore!!!", __func__);
3589 return -EAGAIN;
3590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003591
3592 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003593 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 )
3595 {
3596 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3597 (eCSR_ENCRYPT_TYPE_TKIP !=
3598 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3599 (eCSR_ENCRYPT_TYPE_AES !=
3600 pWextState->roamProfile.EncryptionType.encryptionType[0])
3601 )
3602 {
3603 /* if default key index is not same as previous one,
3604 * then update the default key index */
3605
3606 tCsrRoamSetKey setKey;
3607 v_U32_t roamId= 0xFF;
3608 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3609
3610 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3611 __func__, key_index);
3612
3613 Keys->defaultIndex = (u8)key_index;
3614 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3615 setKey.keyId = key_index;
3616 setKey.keyLength = Keys->KeyLength[key_index];
3617
3618 vos_mem_copy(&setKey.Key[0],
3619 &Keys->KeyMaterial[key_index][0],
3620 Keys->KeyLength[key_index]);
3621
3622 setKey.keyDirection = eSIR_TX_ONLY;
3623
3624 vos_mem_copy(setKey.peerMac,
3625 &pHddStaCtx->conn_info.bssId[0],
3626 WNI_CFG_BSSID_LEN);
3627
3628 setKey.encType =
3629 pWextState->roamProfile.EncryptionType.encryptionType[0];
3630
3631 /* issue set key request */
3632 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3633 pAdapter->sessionId, &setKey, &roamId );
3634
3635 if ( 0 != status )
3636 {
3637 hddLog(VOS_TRACE_LEVEL_ERROR,
3638 "%s: sme_RoamSetKey failed, returned %d", __func__,
3639 status);
3640 return -EINVAL;
3641 }
3642 }
3643 }
3644
3645 /* In SoftAp mode setting key direction for default mode */
3646 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3647 {
3648 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3649 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3650 (eCSR_ENCRYPT_TYPE_AES !=
3651 pWextState->roamProfile.EncryptionType.encryptionType[0])
3652 )
3653 {
3654 /* Saving key direction for default key index to TX default */
3655 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3656 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3657 }
3658 }
3659
3660 return status;
3661}
3662
Jeff Johnson295189b2012-06-20 16:38:30 -07003663/*
3664 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3665 * This function is used to inform the BSS details to nl80211 interface.
3666 */
3667static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3668 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3669{
3670 struct net_device *dev = pAdapter->dev;
3671 struct wireless_dev *wdev = dev->ieee80211_ptr;
3672 struct wiphy *wiphy = wdev->wiphy;
3673 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3674 int chan_no;
3675 int ie_length;
3676 const char *ie;
3677 unsigned int freq;
3678 struct ieee80211_channel *chan;
3679 int rssi = 0;
3680 struct cfg80211_bss *bss = NULL;
3681
3682 ENTER();
3683
3684 if( NULL == pBssDesc )
3685 {
3686 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3687 return bss;
3688 }
3689
3690 chan_no = pBssDesc->channelId;
3691 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3692 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3693
3694 if( NULL == ie )
3695 {
3696 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3697 return bss;
3698 }
3699
3700#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3701 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3702 {
3703 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3704 }
3705 else
3706 {
3707 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3708 }
3709#else
3710 freq = ieee80211_channel_to_frequency(chan_no);
3711#endif
3712
3713 chan = __ieee80211_get_channel(wiphy, freq);
3714
3715 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3716 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3717 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3718 if (bss == NULL)
3719 {
3720 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3721
3722 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3723 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3724 pBssDesc->capabilityInfo,
3725 pBssDesc->beaconInterval, ie, ie_length,
3726 rssi, GFP_KERNEL ));
3727}
3728 else
3729 {
3730 return bss;
3731 }
3732}
3733
3734
3735
3736/*
3737 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3738 * This function is used to inform the BSS details to nl80211 interface.
3739 */
3740struct cfg80211_bss*
3741wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3742 tSirBssDescription *bss_desc
3743 )
3744{
3745 /*
3746 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3747 already exists in bss data base of cfg80211 for that particular BSS ID.
3748 Using cfg80211_inform_bss_frame to update the bss entry instead of
3749 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3750 now there is no possibility to get the mgmt(probe response) frame from PE,
3751 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3752 cfg80211_inform_bss_frame.
3753 */
3754 struct net_device *dev = pAdapter->dev;
3755 struct wireless_dev *wdev = dev->ieee80211_ptr;
3756 struct wiphy *wiphy = wdev->wiphy;
3757 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003758#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3759 qcom_ie_age *qie_age = NULL;
3760 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3761#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003762 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003764 const char *ie =
3765 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3766 unsigned int freq;
3767 struct ieee80211_channel *chan;
3768 struct ieee80211_mgmt *mgmt =
3769 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3770 struct cfg80211_bss *bss_status = NULL;
3771 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3772 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003773#ifdef WLAN_OPEN_SOURCE
3774 struct timespec ts;
3775#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003776
3777 ENTER();
3778
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003779 if (!mgmt)
3780 return NULL;
3781
Jeff Johnson295189b2012-06-20 16:38:30 -07003782 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003783
3784#ifdef WLAN_OPEN_SOURCE
3785 /* Android does not want the timestamp from the frame.
3786 Instead it wants a monotonic increasing value */
3787 get_monotonic_boottime(&ts);
3788 mgmt->u.probe_resp.timestamp =
3789 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3790#else
3791 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003792 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3793 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003794
3795#endif
3796
Jeff Johnson295189b2012-06-20 16:38:30 -07003797 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3798 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003799
3800#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3801 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3802 /* Assuming this is the last IE, copy at the end */
3803 ie_length -=sizeof(qcom_ie_age);
3804 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3805 qie_age->element_id = QCOM_VENDOR_IE_ID;
3806 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3807 qie_age->oui_1 = QCOM_OUI1;
3808 qie_age->oui_2 = QCOM_OUI2;
3809 qie_age->oui_3 = QCOM_OUI3;
3810 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3811 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3812#endif
3813
Jeff Johnson295189b2012-06-20 16:38:30 -07003814 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3815
3816 mgmt->frame_control |=
3817 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3818
3819#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3820 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3821 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3822 {
3823 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3824 }
3825 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3826 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3827
3828 {
3829 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3830 }
3831 else
3832 {
3833 kfree(mgmt);
3834 return NULL;
3835 }
3836#else
3837 freq = ieee80211_channel_to_frequency(chan_no);
3838#endif
3839 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003840 /*when the band is changed on the fly using the GUI, three things are done
3841 * 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)
3842 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3843 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3844 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3845 * and discards the channels correponding to previous band and calls back with zero bss results.
3846 * 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
3847 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3848 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3849 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3850 * So drop the bss and continue to next bss.
3851 */
3852 if(chan == NULL)
3853 {
3854 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3855 return NULL;
3856 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003857 /*To keep the rssi icon of the connected AP in the scan window
3858 *and the rssi icon of the wireless networks in sync
3859 * */
3860 if (( eConnectionState_Associated ==
3861 pAdapter->sessionCtx.station.conn_info.connState ) &&
3862 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3863 pAdapter->sessionCtx.station.conn_info.bssId,
3864 WNI_CFG_BSSID_LEN)))
3865 {
3866 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3867 rssi = (pAdapter->rssi * 100);
3868 }
3869 else
3870 {
3871 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3872 }
3873
3874 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3875 frame_len, rssi, GFP_KERNEL);
3876 kfree(mgmt);
3877 return bss_status;
3878}
3879
3880/*
3881 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3882 * This function is used to update the BSS data base of CFG8011
3883 */
3884struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3885 tCsrRoamInfo *pRoamInfo
3886 )
3887{
3888 tCsrRoamConnectedProfile roamProfile;
3889 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3890 struct cfg80211_bss *bss = NULL;
3891
3892 ENTER();
3893
3894 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3895 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3896
3897 if (NULL != roamProfile.pBssDesc)
3898 {
3899 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3900 &roamProfile);
3901
3902 if (NULL == bss)
3903 {
3904 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3905 __func__);
3906 }
3907
3908 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3909 }
3910 else
3911 {
3912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3913 __func__);
3914 }
3915 return bss;
3916}
3917
3918/*
3919 * FUNCTION: wlan_hdd_cfg80211_update_bss
3920 */
3921static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3922 hdd_adapter_t *pAdapter
3923 )
3924{
3925 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3926 tCsrScanResultInfo *pScanResult;
3927 eHalStatus status = 0;
3928 tScanResultHandle pResult;
3929 struct cfg80211_bss *bss_status = NULL;
3930
3931 ENTER();
3932
3933 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3934 {
3935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3936 return -EAGAIN;
3937 }
3938
3939 /*
3940 * start getting scan results and populate cgf80211 BSS database
3941 */
3942 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3943
3944 /* no scan results */
3945 if (NULL == pResult)
3946 {
3947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3948 return status;
3949 }
3950
3951 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3952
3953 while (pScanResult)
3954 {
3955 /*
3956 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3957 * entry already exists in bss data base of cfg80211 for that
3958 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3959 * bss entry instead of cfg80211_inform_bss, But this call expects
3960 * mgmt packet as input. As of now there is no possibility to get
3961 * the mgmt(probe response) frame from PE, converting bss_desc to
3962 * ieee80211_mgmt(probe response) and passing to c
3963 * fg80211_inform_bss_frame.
3964 * */
3965
3966 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3967 &pScanResult->BssDescriptor);
3968
3969
3970 if (NULL == bss_status)
3971 {
3972 hddLog(VOS_TRACE_LEVEL_INFO,
3973 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3974 }
3975 else
3976 {
3977 cfg80211_put_bss(bss_status);
3978 }
3979
3980 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3981 }
3982
3983 sme_ScanResultPurge(hHal, pResult);
3984
3985 return 0;
3986}
3987
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003988void
3989hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3990{
3991 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003992 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3993 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3994 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003995} /****** end hddPrintMacAddr() ******/
3996
3997void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003998hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003999{
4000 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004001 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4002 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4003 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4004 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004005} /****** end hddPrintPmkId() ******/
4006
4007//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4008//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4009
4010//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4011//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4012
4013#define dump_bssid(bssid) \
4014 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004015 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4016 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4017 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004018 }
4019
4020#define dump_pmkid(pMac, pmkid) \
4021 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004022 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4023 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4024 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004025 }
4026
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004027#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004028/*
4029 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4030 * This function is used to notify the supplicant of a new PMKSA candidate.
4031 */
4032int wlan_hdd_cfg80211_pmksa_candidate_notify(
4033 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
4034 int index, bool preauth )
4035{
Jeff Johnsone7245742012-09-05 17:12:55 -07004036#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004037 struct net_device *dev = pAdapter->dev;
4038
4039 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004040 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004041
4042 if( NULL == pRoamInfo )
4043 {
4044 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4045 return -EINVAL;
4046 }
4047
4048 dump_bssid(pRoamInfo->bssid);
4049 cfg80211_pmksa_candidate_notify(dev, index,
4050 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07004051#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004052 return 0;
4053}
4054#endif //FEATURE_WLAN_LFR
4055
Jeff Johnson295189b2012-06-20 16:38:30 -07004056/*
4057 * FUNCTION: hdd_cfg80211_scan_done_callback
4058 * scanning callback function, called after finishing scan
4059 *
4060 */
4061static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
4062 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4063{
4064 struct net_device *dev = (struct net_device *) pContext;
4065 //struct wireless_dev *wdev = dev->ieee80211_ptr;
4066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004067 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4068 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 struct cfg80211_scan_request *req = NULL;
4070 int ret = 0;
4071
4072 ENTER();
4073
4074 hddLog(VOS_TRACE_LEVEL_INFO,
4075 "%s called with halHandle = %p, pContext = %p,"
4076 "scanID = %d, returned status = %d\n",
4077 __func__, halHandle, pContext, (int) scanId, (int) status);
4078
4079 //Block on scan req completion variable. Can't wait forever though.
4080 ret = wait_for_completion_interruptible_timeout(
4081 &pScanInfo->scan_req_completion_event,
4082 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4083 if (!ret)
4084 {
4085 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004086 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004087 }
4088
4089 if(pScanInfo->mScanPending != VOS_TRUE)
4090 {
4091 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004092 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004093 }
4094
4095 /* Check the scanId */
4096 if (pScanInfo->scanId != scanId)
4097 {
4098 hddLog(VOS_TRACE_LEVEL_INFO,
4099 "%s called with mismatched scanId pScanInfo->scanId = %d "
4100 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
4101 (int) scanId);
4102 }
4103
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
4105 pAdapter);
4106
4107 if (0 > ret)
4108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
4109
4110
4111 /* If any client wait scan result through WEXT
4112 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004113 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004114 {
4115 /* The other scan request waiting for current scan finish
4116 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004117 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004118 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004119 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004120 }
4121 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004122 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004123 {
4124 struct net_device *dev = pAdapter->dev;
4125 union iwreq_data wrqu;
4126 int we_event;
4127 char *msg;
4128
4129 memset(&wrqu, '\0', sizeof(wrqu));
4130 we_event = SIOCGIWSCAN;
4131 msg = NULL;
4132 wireless_send_event(dev, we_event, &wrqu, msg);
4133 }
4134 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004135 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004136
4137 /* Get the Scan Req */
4138 req = pAdapter->request;
4139
4140 if (!req)
4141 {
4142 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004143 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004144 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004145 }
4146
4147 /*
4148 * setting up 0, just in case.
4149 */
4150 req->n_ssids = 0;
4151 req->n_channels = 0;
4152 req->ie = 0;
4153
Jeff Johnson295189b2012-06-20 16:38:30 -07004154 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004155 /* Scan is no longer pending */
4156 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004157
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004158 /*
4159 * cfg80211_scan_done informing NL80211 about completion
4160 * of scanning
4161 */
4162 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004163 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004164
Jeff Johnsone7245742012-09-05 17:12:55 -07004165allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004166 /* release the wake lock at the end of the scan*/
4167 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004168
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004169 /* Acquire wakelock to handle the case where APP's tries to suspend
4170 * immediatly after the driver gets connect request(i.e after scan)
4171 * from supplicant, this result in app's is suspending and not able
4172 * to process the connect request to AP */
4173 hdd_allow_suspend_timeout(100);
4174
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 EXIT();
4176 return 0;
4177}
4178
4179/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004180 * FUNCTION: hdd_isScanAllowed
4181 * Go through each adapter and check if scan allowed
4182 *
4183 */
4184v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4185{
4186 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4187 hdd_station_ctx_t *pHddStaCtx = NULL;
4188 hdd_adapter_t *pAdapter = NULL;
4189 VOS_STATUS status = 0;
4190 v_U8_t staId = 0;
4191 v_U8_t *staMac = NULL;
4192
4193 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4194
4195 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4196 {
4197 pAdapter = pAdapterNode->pAdapter;
4198
4199 if( pAdapter )
4200 {
4201 hddLog(VOS_TRACE_LEVEL_INFO,
4202 "%s: Adapter with device mode %d exists",
4203 __func__, pAdapter->device_mode);
4204 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4205 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4206 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4207 {
4208 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4209 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4210 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4211 {
4212 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4213 hddLog(VOS_TRACE_LEVEL_ERROR,
4214 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4215 "middle of WPS/EAPOL exchange.", __func__,
4216 staMac[0], staMac[1], staMac[2],
4217 staMac[3], staMac[4], staMac[5]);
4218 return VOS_FALSE;
4219 }
4220 }
4221 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4222 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4223 {
4224 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4225 {
4226 if ((pAdapter->aStaInfo[staId].isUsed) &&
4227 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4228 {
4229 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4230
4231 hddLog(VOS_TRACE_LEVEL_ERROR,
4232 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4233 "middle of WPS/EAPOL exchange.", __func__,
4234 staMac[0], staMac[1], staMac[2],
4235 staMac[3], staMac[4], staMac[5]);
4236 return VOS_FALSE;
4237 }
4238 }
4239 }
4240 }
4241 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4242 pAdapterNode = pNext;
4243 }
4244 hddLog(VOS_TRACE_LEVEL_INFO,
4245 "%s: Scan allowed", __func__);
4246 return VOS_TRUE;
4247}
4248
4249/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 * FUNCTION: wlan_hdd_cfg80211_scan
4251 * this scan respond to scan trigger and update cfg80211 scan database
4252 * later, scan dump command can be used to recieve scan results
4253 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004254int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4255#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4256 struct net_device *dev,
4257#endif
4258 struct cfg80211_scan_request *request)
4259{
4260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4261 struct net_device *dev = request->wdev->netdev;
4262#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4264 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4265 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4266 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4267 tCsrScanRequest scanRequest;
4268 tANI_U8 *channelList = NULL, i;
4269 v_U32_t scanId = 0;
4270 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004271 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004272 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004273
4274 ENTER();
4275
4276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4277 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004278
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004279 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004280 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004281 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004282 {
4283 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004284 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4285 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004286 return -EBUSY;
4287 }
4288
Jeff Johnson295189b2012-06-20 16:38:30 -07004289#ifdef WLAN_BTAMP_FEATURE
4290 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004291 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004293 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004294 "%s: No scanning when AMP is on", __func__);
4295 return -EOPNOTSUPP;
4296 }
4297#endif
4298 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004299 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004300 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004301 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004302 "%s: Not scanning on device_mode = %d",
4303 __func__, pAdapter->device_mode);
4304 return -EOPNOTSUPP;
4305 }
4306
4307 if (TRUE == pScanInfo->mScanPending)
4308 {
4309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004310 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004311 }
4312
4313 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4314 {
4315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4316 "%s:LOGP in Progress. Ignore!!!", __func__);
4317 return -EAGAIN;
4318 }
4319
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004320 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4321 {
4322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4323 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4324 return -EAGAIN;
4325 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004326 //Don't Allow Scan and return busy if Remain On
4327 //Channel and action frame is pending
4328 //Otherwise Cancel Remain On Channel and allow Scan
4329 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004330 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004331 {
4332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4333 return -EBUSY;
4334 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004335#ifdef FEATURE_WLAN_TDLS
4336 if (wlan_hdd_tdlsConnectedPeers(pAdapter))
4337 {
4338 tANI_U8 staIdx;
4339
4340 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
4341 {
4342 if (pHddCtx->tdlsConnInfo[staIdx].staId)
4343 {
4344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4345 ("scan: indicate TDLS teadown (staId %d)"), pHddCtx->tdlsConnInfo[staIdx].staId) ;
4346
4347#ifdef CONFIG_TDLS_IMPLICIT
4348 cfg80211_tdls_oper_request(pAdapter->dev,
4349 pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes,
4350 NL80211_TDLS_TEARDOWN,
4351 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
4352 GFP_KERNEL);
4353#endif
4354 }
4355 }
4356 return -EBUSY;
4357 }
4358#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004359
Jeff Johnson295189b2012-06-20 16:38:30 -07004360 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4361 {
4362 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004363 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004364 return -EAGAIN;
4365 }
4366 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4367 {
4368 hddLog(VOS_TRACE_LEVEL_WARN,
4369 "%s: MAX TM Level Scan not allowed", __func__);
4370 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4371 return -EBUSY;
4372 }
4373 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4374
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004375 /* Check if scan is allowed at this point of time.
4376 */
4377 if (!hdd_isScanAllowed(pHddCtx))
4378 {
4379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4380 return -EBUSY;
4381 }
4382
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4384
4385 if (NULL != request)
4386 {
4387 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4388 (int)request->n_ssids);
4389
4390 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4391 * Becasue of this, driver is assuming that this is not wildcard scan and so
4392 * is not aging out the scan results.
4393 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004394 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004395 {
4396 request->n_ssids = 0;
4397 }
4398
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004399 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004400 {
4401 tCsrSSIDInfo *SsidInfo;
4402 int j;
4403 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4404 /* Allocate num_ssid tCsrSSIDInfo structure */
4405 SsidInfo = scanRequest.SSIDs.SSIDList =
4406 ( tCsrSSIDInfo *)vos_mem_malloc(
4407 request->n_ssids*sizeof(tCsrSSIDInfo));
4408
4409 if(NULL == scanRequest.SSIDs.SSIDList)
4410 {
4411 hddLog(VOS_TRACE_LEVEL_ERROR,
4412 "memory alloc failed SSIDInfo buffer");
4413 return -ENOMEM;
4414 }
4415
4416 /* copy all the ssid's and their length */
4417 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4418 {
4419 /* get the ssid length */
4420 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4421 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4422 SsidInfo->SSID.length);
4423 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4424 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4425 j, SsidInfo->SSID.ssId);
4426 }
4427 /* set the scan type to active */
4428 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4429 }
4430 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4431 {
4432 /* set the scan type to active */
4433 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4434 }
4435 else
4436 {
4437 /*Set the scan type to default type, in this case it is ACTIVE*/
4438 scanRequest.scanType = pScanInfo->scan_mode;
4439 }
4440 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4441 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4442 }
4443 else
4444 {
4445 /* set the scan type to active */
4446 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4447 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4448
4449 /* set min and max channel time to zero */
4450 scanRequest.minChnTime = 0;
4451 scanRequest.maxChnTime = 0;
4452 }
4453
4454 /* set BSSType to default type */
4455 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4456
4457 /*TODO: scan the requested channels only*/
4458
4459 /*Right now scanning all the channels */
4460 if( request )
4461 {
4462 if( request->n_channels )
4463 {
4464 channelList = vos_mem_malloc( request->n_channels );
4465 if( NULL == channelList )
4466 {
4467 status = -ENOMEM;
4468 goto free_mem;
4469 }
4470
4471 for( i = 0 ; i < request->n_channels ; i++ )
4472 channelList[i] = request->channels[i]->hw_value;
4473 }
4474
4475 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4476 scanRequest.ChannelInfo.ChannelList = channelList;
4477
4478 /* set requestType to full scan */
4479 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004480
4481 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4482 * search (Flush on both full scan and social scan but not on single
4483 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4484 */
4485
4486 /* Supplicant does single channel scan after 8-way handshake
4487 * and in that case driver shoudnt flush scan results. If
4488 * driver flushes the scan results here and unfortunately if
4489 * the AP doesnt respond to our probe req then association
4490 * fails which is not desired
4491 */
4492
4493 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4494 {
4495 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4496 pAdapter->sessionId );
4497 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004498
4499 if( request->ie_len )
4500 {
4501 /* save this for future association (join requires this) */
4502 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4503 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4504 pScanInfo->scanAddIE.length = request->ie_len;
4505
4506 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004507 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4508 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004509 )
4510 {
4511 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4512 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4513 }
4514
4515 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4516 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4517
Jeff Johnson295189b2012-06-20 16:38:30 -07004518 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4519 request->ie_len);
4520 if (pP2pIe != NULL)
4521 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004522#ifdef WLAN_FEATURE_P2P_DEBUG
4523 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4524 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4525 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4526 {
4527 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4528 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4529 "Go nego completed to Connection is started");
4530 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4531 "for 8way Handshake");
4532 }
4533 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4534 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4535 {
4536 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4537 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4538 "Disconnected state to Connection is started");
4539 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4540 "for 4way Handshake");
4541 }
4542#endif
4543
Jeff Johnsone7245742012-09-05 17:12:55 -07004544 /* no_cck will be set during p2p find to disable 11b rates */
4545 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004546 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004547 hddLog(VOS_TRACE_LEVEL_INFO,
4548 "%s: This is a P2P Search", __func__);
4549 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004550
Jeff Johnsone7245742012-09-05 17:12:55 -07004551 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4552 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004553 /* set requestType to P2P Discovery */
4554 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004555 }
4556
4557 /*
4558 Skip Dfs Channel in case of P2P Search
4559 if it is set in ini file
4560 */
4561 if(cfg_param->skipDfsChnlInP2pSearch)
4562 {
4563 scanRequest.skipDfsChnlInP2pSearch = 1;
4564 }
4565 else
4566 {
4567 scanRequest.skipDfsChnlInP2pSearch = 0;
4568 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004569
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 }
4571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 }
4573 }
4574
4575 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4576
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004577 /* acquire the wakelock to avoid the apps suspend during the scan. To
4578 * address the following issues.
4579 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4580 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4581 * for long time, this result in apps running at full power for long time.
4582 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4583 * be stuck in full power because of resume BMPS
4584 */
4585 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004586
4587 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004588 pAdapter->sessionId, &scanRequest, &scanId,
4589 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004590
Jeff Johnson295189b2012-06-20 16:38:30 -07004591 if (eHAL_STATUS_SUCCESS != status)
4592 {
4593 hddLog(VOS_TRACE_LEVEL_ERROR,
4594 "%s: sme_ScanRequest returned error %d", __func__, status);
4595 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004596 if(eHAL_STATUS_RESOURCES == status)
4597 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004598 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 -07004599 status = -EBUSY;
4600 } else {
4601 status = -EIO;
4602 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004603 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004604 goto free_mem;
4605 }
4606
4607 pScanInfo->mScanPending = TRUE;
4608 pAdapter->request = request;
4609 pScanInfo->scanId = scanId;
4610
4611 complete(&pScanInfo->scan_req_completion_event);
4612
4613free_mem:
4614 if( scanRequest.SSIDs.SSIDList )
4615 {
4616 vos_mem_free(scanRequest.SSIDs.SSIDList);
4617 }
4618
4619 if( channelList )
4620 vos_mem_free( channelList );
4621
4622 EXIT();
4623
4624 return status;
4625}
4626
4627/*
4628 * FUNCTION: wlan_hdd_cfg80211_connect_start
4629 * This function is used to start the association process
4630 */
4631int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004632 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004633{
4634 int status = 0;
4635 hdd_wext_state_t *pWextState;
4636 v_U32_t roamId;
4637 tCsrRoamProfile *pRoamProfile;
4638 eMib_dot11DesiredBssType connectedBssType;
4639 eCsrAuthType RSNAuthType;
4640
4641 ENTER();
4642
4643 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4644
4645 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4646 {
4647 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4648 return -EINVAL;
4649 }
4650
4651 pRoamProfile = &pWextState->roamProfile;
4652
4653 if (pRoamProfile)
4654 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004655 int ret = 0;
4656 hdd_station_ctx_t *pHddStaCtx;
4657 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4658 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4659
4660 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4661 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4662 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004663 {
4664 /* Issue disconnect to CSR */
4665 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4666 if( eHAL_STATUS_SUCCESS ==
4667 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4668 pAdapter->sessionId,
4669 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4670 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004671 ret = wait_for_completion_interruptible_timeout(
4672 &pAdapter->disconnect_comp_var,
4673 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4674 if (0 == ret)
4675 {
4676 VOS_ASSERT(0);
4677 }
4678 }
4679 }
4680 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4681 {
4682 ret = wait_for_completion_interruptible_timeout(
4683 &pAdapter->disconnect_comp_var,
4684 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4685 if (0 == ret)
4686 {
4687 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004688 }
4689 }
4690
4691 if (HDD_WMM_USER_MODE_NO_QOS ==
4692 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4693 {
4694 /*QoS not enabled in cfg file*/
4695 pRoamProfile->uapsd_mask = 0;
4696 }
4697 else
4698 {
4699 /*QoS enabled, update uapsd mask from cfg file*/
4700 pRoamProfile->uapsd_mask =
4701 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4702 }
4703
4704 pRoamProfile->SSIDs.numOfSSIDs = 1;
4705 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4706 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4707 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4708 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4709 ssid, ssid_len);
4710
4711 if (bssid)
4712 {
4713 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4714 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4715 WNI_CFG_BSSID_LEN);
4716 /* Save BSSID in seperate variable as well, as RoamProfile
4717 BSSID is getting zeroed out in the association process. And in
4718 case of join failure we should send valid BSSID to supplicant
4719 */
4720 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4721 WNI_CFG_BSSID_LEN);
4722 }
4723
4724 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4725 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4726 {
4727 /*set gen ie*/
4728 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4729 /*set auth*/
4730 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4731 }
4732 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4733 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4734 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4735 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4736 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4737 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4738 )
4739 {
4740 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4741 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4742 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4743 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4744 eCSR_AUTH_TYPE_AUTOSWITCH;
4745 pWextState->roamProfile.AuthType.authType[0] =
4746 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4747 }
4748#ifdef FEATURE_WLAN_WAPI
4749 if (pAdapter->wapi_info.nWapiMode)
4750 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004751 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004752 switch (pAdapter->wapi_info.wapiAuthMode)
4753 {
4754 case WAPI_AUTH_MODE_PSK:
4755 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004756 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004757 pAdapter->wapi_info.wapiAuthMode);
4758 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4759 break;
4760 }
4761 case WAPI_AUTH_MODE_CERT:
4762 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004763 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004764 pAdapter->wapi_info.wapiAuthMode);
4765 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4766 break;
4767 }
4768 } // End of switch
4769 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4770 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4771 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004772 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004773 pRoamProfile->AuthType.numEntries = 1;
4774 pRoamProfile->EncryptionType.numEntries = 1;
4775 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4776 pRoamProfile->mcEncryptionType.numEntries = 1;
4777 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4778 }
4779 }
4780#endif /* FEATURE_WLAN_WAPI */
4781 pRoamProfile->csrPersona = pAdapter->device_mode;
4782
Jeff Johnson32d95a32012-09-10 13:15:23 -07004783 if( operatingChannel )
4784 {
4785 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4786 pRoamProfile->ChannelInfo.numOfChannels = 1;
4787 }
4788
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004789 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4790 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4791 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4792 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004793 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4794 */
4795 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4796 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4797 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004798
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4800 pAdapter->sessionId, pRoamProfile, &roamId);
4801
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004802 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304803 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4804
4805 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4807 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4808 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304809 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004810 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304811 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004812
4813 pRoamProfile->ChannelInfo.ChannelList = NULL;
4814 pRoamProfile->ChannelInfo.numOfChannels = 0;
4815
Jeff Johnson295189b2012-06-20 16:38:30 -07004816 }
4817 else
4818 {
4819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4820 return -EINVAL;
4821 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004822 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004823 return status;
4824}
4825
4826/*
4827 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4828 * This function is used to set the authentication type (OPEN/SHARED).
4829 *
4830 */
4831static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4832 enum nl80211_auth_type auth_type)
4833{
4834 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4836
4837 ENTER();
4838
4839 /*set authentication type*/
4840 switch (auth_type)
4841 {
4842 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4843 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004844#ifdef WLAN_FEATURE_VOWIFI_11R
4845 case NL80211_AUTHTYPE_FT:
4846#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 hddLog(VOS_TRACE_LEVEL_INFO,
4848 "%s: set authentication type to OPEN", __func__);
4849 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4850 break;
4851
4852 case NL80211_AUTHTYPE_SHARED_KEY:
4853 hddLog(VOS_TRACE_LEVEL_INFO,
4854 "%s: set authentication type to SHARED", __func__);
4855 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4856 break;
4857#ifdef FEATURE_WLAN_CCX
4858 case NL80211_AUTHTYPE_NETWORK_EAP:
4859 hddLog(VOS_TRACE_LEVEL_INFO,
4860 "%s: set authentication type to CCKM WPA", __func__);
4861 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4862 break;
4863#endif
4864
4865
4866 default:
4867 hddLog(VOS_TRACE_LEVEL_ERROR,
4868 "%s: Unsupported authentication type %d", __func__,
4869 auth_type);
4870 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4871 return -EINVAL;
4872 }
4873
4874 pWextState->roamProfile.AuthType.authType[0] =
4875 pHddStaCtx->conn_info.authType;
4876 return 0;
4877}
4878
4879/*
4880 * FUNCTION: wlan_hdd_set_akm_suite
4881 * This function is used to set the key mgmt type(PSK/8021x).
4882 *
4883 */
4884static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4885 u32 key_mgmt
4886 )
4887{
4888 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4889 ENTER();
4890
4891 /*set key mgmt type*/
4892 switch(key_mgmt)
4893 {
4894 case WLAN_AKM_SUITE_PSK:
4895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4896 __func__);
4897 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4898 break;
4899
4900 case WLAN_AKM_SUITE_8021X:
4901 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4902 __func__);
4903 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4904 break;
4905#ifdef FEATURE_WLAN_CCX
4906#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4907#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4908 case WLAN_AKM_SUITE_CCKM:
4909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4910 __func__);
4911 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4912 break;
4913#endif
4914
4915 default:
4916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4917 __func__, key_mgmt);
4918 return -EINVAL;
4919
4920 }
4921 return 0;
4922}
4923
4924/*
4925 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4926 * This function is used to set the encryption type
4927 * (NONE/WEP40/WEP104/TKIP/CCMP).
4928 */
4929static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4930 u32 cipher,
4931 bool ucast
4932 )
4933{
4934 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4935 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4936 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4937
4938 ENTER();
4939
4940 if (!cipher)
4941 {
4942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4943 __func__, cipher);
4944 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4945 }
4946 else
4947 {
4948
4949 /*set encryption method*/
4950 switch (cipher)
4951 {
4952 case IW_AUTH_CIPHER_NONE:
4953 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4954 break;
4955
4956 case WLAN_CIPHER_SUITE_WEP40:
4957 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4958 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4959 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4960 else
4961 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4962 break;
4963
4964 case WLAN_CIPHER_SUITE_WEP104:
4965 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4966 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4967 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4968 else
4969 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4970 break;
4971
4972 case WLAN_CIPHER_SUITE_TKIP:
4973 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4974 break;
4975
4976 case WLAN_CIPHER_SUITE_CCMP:
4977 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4978 break;
4979#ifdef FEATURE_WLAN_WAPI
4980 case WLAN_CIPHER_SUITE_SMS4:
4981 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4982 break;
4983#endif
4984
4985#ifdef FEATURE_WLAN_CCX
4986 case WLAN_CIPHER_SUITE_KRK:
4987 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4988 break;
4989#endif
4990 default:
4991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4992 __func__, cipher);
4993 return -EOPNOTSUPP;
4994 }
4995 }
4996
4997 if (ucast)
4998 {
4999 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
5000 __func__, encryptionType);
5001 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5002 pWextState->roamProfile.EncryptionType.numEntries = 1;
5003 pWextState->roamProfile.EncryptionType.encryptionType[0] =
5004 encryptionType;
5005 }
5006 else
5007 {
5008 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
5009 __func__, encryptionType);
5010 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5011 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5012 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5013 }
5014
5015 return 0;
5016}
5017
5018
5019/*
5020 * FUNCTION: wlan_hdd_cfg80211_set_ie
5021 * This function is used to parse WPA/RSN IE's.
5022 */
5023int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5024 u8 *ie,
5025 size_t ie_len
5026 )
5027{
5028 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5029 u8 *genie = ie;
5030 v_U16_t remLen = ie_len;
5031#ifdef FEATURE_WLAN_WAPI
5032 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5033 u16 *tmp;
5034 v_U16_t akmsuiteCount;
5035 int *akmlist;
5036#endif
5037 ENTER();
5038
5039 /* clear previous assocAddIE */
5040 pWextState->assocAddIE.length = 0;
5041 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5042
5043 while (remLen >= 2)
5044 {
5045 v_U16_t eLen = 0;
5046 v_U8_t elementId;
5047 elementId = *genie++;
5048 eLen = *genie++;
5049 remLen -= 2;
5050
5051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
5052 __func__, elementId, eLen);
5053
5054 switch ( elementId )
5055 {
5056 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005057 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 -07005058 {
5059 hddLog(VOS_TRACE_LEVEL_ERROR,
5060 "%s: Invalid WPA IE", __func__);
5061 return -EINVAL;
5062 }
5063 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
5064 {
5065 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5066 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
5067 __func__, eLen + 2);
5068
5069 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5070 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005071 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5072 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005073 VOS_ASSERT(0);
5074 return -ENOMEM;
5075 }
5076 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5077 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5078 pWextState->assocAddIE.length += eLen + 2;
5079
5080 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5081 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5082 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5083 }
5084 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5085 {
5086 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5087 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5088 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5089 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5090 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5091 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5093 P2P_OUI_TYPE_SIZE))
5094 /*Consider P2P IE, only for P2P Client */
5095 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5096 {
5097 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5098 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
5099 __func__, eLen + 2);
5100
5101 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5102 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005103 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5104 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 VOS_ASSERT(0);
5106 return -ENOMEM;
5107 }
5108 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5109 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5110 pWextState->assocAddIE.length += eLen + 2;
5111
5112 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5113 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005115#ifdef WLAN_FEATURE_WFD
5116 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5117 WFD_OUI_TYPE_SIZE))
5118 /*Consider WFD IE, only for P2P Client */
5119 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5120 {
5121 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5122 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
5123 __func__, eLen + 2);
5124
5125 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5126 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005127 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5128 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 VOS_ASSERT(0);
5130 return -ENOMEM;
5131 }
5132 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5133 // WPS IE + P2P IE + WFD IE
5134 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5135 pWextState->assocAddIE.length += eLen + 2;
5136
5137 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5138 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5139 }
5140#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005141 /* Appending HS 2.0 Indication Element in Assiciation Request */
5142 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005143 HS20_OUI_TYPE_SIZE)) )
5144 {
5145 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5146 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
5147 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005148
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005149 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5150 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005151 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5152 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005153 VOS_ASSERT(0);
5154 return -ENOMEM;
5155 }
5156 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5157 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005158
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005159 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5160 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5161 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005162
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 break;
5164 case DOT11F_EID_RSN:
5165 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5166 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5167 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5168 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5169 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5170 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005171 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5172 case DOT11F_EID_EXTCAP:
5173 {
5174 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5175 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5176 __func__, eLen + 2);
5177
5178 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5179 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005180 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5181 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005182 VOS_ASSERT(0);
5183 return -ENOMEM;
5184 }
5185 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5186 pWextState->assocAddIE.length += eLen + 2;
5187
5188 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5189 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5190 break;
5191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005192#ifdef FEATURE_WLAN_WAPI
5193 case WLAN_EID_WAPI:
5194 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5195 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5196 pAdapter->wapi_info.nWapiMode);
5197 tmp = (u16 *)ie;
5198 tmp = tmp + 2; // Skip element Id and Len, Version
5199 akmsuiteCount = WPA_GET_LE16(tmp);
5200 tmp = tmp + 1;
5201 akmlist = (int *)(tmp);
5202 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5203 {
5204 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5205 }
5206 else
5207 {
5208 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5209 VOS_ASSERT(0);
5210 return -EINVAL;
5211 }
5212
5213 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5214 {
5215 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005216 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005217 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5218 }
5219 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5220 {
5221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005222 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005223 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5224 }
5225 break;
5226#endif
5227 default:
5228 hddLog (VOS_TRACE_LEVEL_ERROR,
5229 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005230 /* when Unknown IE is received we should break and continue
5231 * to the next IE in the buffer instead we were returning
5232 * so changing this to break */
5233 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005234 }
5235 genie += eLen;
5236 remLen -= eLen;
5237 }
5238 EXIT();
5239 return 0;
5240}
5241
5242/*
5243 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5244 * This function is used to initialize the security
5245 * parameters during connect operation.
5246 */
5247int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5248 struct cfg80211_connect_params *req
5249 )
5250{
5251 int status = 0;
5252 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5253 ENTER();
5254
5255 /*set wpa version*/
5256 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5257
5258 if (req->crypto.wpa_versions)
5259 {
5260 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5261 && ( (req->ie_len)
5262 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5263 // Make sure that it is including a WPA IE.
5264 /* Currently NL is putting WPA version 1 even for open,
5265 * since p2p ie is also put in same buffer.
5266 * */
5267 {
5268 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5269 }
5270 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5271 {
5272 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5273 }
5274 }
5275
5276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5277 pWextState->wpaVersion);
5278
5279 /*set authentication type*/
5280 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5281
5282 if (0 > status)
5283 {
5284 hddLog(VOS_TRACE_LEVEL_ERROR,
5285 "%s: failed to set authentication type ", __func__);
5286 return status;
5287 }
5288
5289 /*set key mgmt type*/
5290 if (req->crypto.n_akm_suites)
5291 {
5292 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5293 if (0 > status)
5294 {
5295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5296 __func__);
5297 return status;
5298 }
5299 }
5300
5301 /*set pairwise cipher type*/
5302 if (req->crypto.n_ciphers_pairwise)
5303 {
5304 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5305 req->crypto.ciphers_pairwise[0], true);
5306 if (0 > status)
5307 {
5308 hddLog(VOS_TRACE_LEVEL_ERROR,
5309 "%s: failed to set unicast cipher type", __func__);
5310 return status;
5311 }
5312 }
5313 else
5314 {
5315 /*Reset previous cipher suite to none*/
5316 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5317 if (0 > status)
5318 {
5319 hddLog(VOS_TRACE_LEVEL_ERROR,
5320 "%s: failed to set unicast cipher type", __func__);
5321 return status;
5322 }
5323 }
5324
5325 /*set group cipher type*/
5326 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5327 false);
5328
5329 if (0 > status)
5330 {
5331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5332 __func__);
5333 return status;
5334 }
5335
5336 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5337 if (req->ie_len)
5338 {
5339 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5340 if ( 0 > status)
5341 {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5343 __func__);
5344 return status;
5345 }
5346 }
5347
5348 /*incase of WEP set default key information*/
5349 if (req->key && req->key_len)
5350 {
5351 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5352 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5353 )
5354 {
5355 if ( IW_AUTH_KEY_MGMT_802_1X
5356 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5357 {
5358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5359 __func__);
5360 return -EOPNOTSUPP;
5361 }
5362 else
5363 {
5364 u8 key_len = req->key_len;
5365 u8 key_idx = req->key_idx;
5366
5367 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5368 && (CSR_MAX_NUM_KEY > key_idx)
5369 )
5370 {
5371 hddLog(VOS_TRACE_LEVEL_INFO,
5372 "%s: setting default wep key, key_idx = %hu key_len %hu",
5373 __func__, key_idx, key_len);
5374 vos_mem_copy(
5375 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5376 req->key, key_len);
5377 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5378 (u8)key_len;
5379 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5380 }
5381 }
5382 }
5383 }
5384
5385 return status;
5386}
5387
5388/*
5389 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5390 * This function is used to initialize the security
5391 * parameters during connect operation.
5392 */
5393static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5394 struct net_device *ndev,
5395 struct cfg80211_connect_params *req
5396 )
5397{
5398 int status = 0;
5399 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5400 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5401 hdd_context_t *pHddCtx = NULL;
5402
5403 ENTER();
5404
5405 hddLog(VOS_TRACE_LEVEL_INFO,
5406 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5407
5408 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5409 {
5410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5411 "%s:LOGP in Progress. Ignore!!!", __func__);
5412 return -EAGAIN;
5413 }
5414
5415#ifdef WLAN_BTAMP_FEATURE
5416 //Infra connect not supported when AMP traffic is on.
5417 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5418 {
5419 hddLog(VOS_TRACE_LEVEL_ERROR,
5420 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005421 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 }
5423#endif
5424 /*initialise security parameters*/
5425 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5426
5427 if ( 0 > status)
5428 {
5429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5430 __func__);
5431 return status;
5432 }
5433
5434 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005435 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5437 (vos_concurrent_sessions_running()))
5438 {
5439 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5440
5441 if (NULL != pVosContext)
5442 {
5443 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5444 if(NULL != pHddCtx)
5445 {
5446 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5447 }
5448 }
5449 }
5450
Mohit Khanna765234a2012-09-11 15:08:35 -07005451 if ( req->channel )
5452 {
5453 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5454 req->ssid_len, req->bssid,
5455 req->channel->hw_value);
5456 }
5457 else
5458 {
5459 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5460 req->ssid_len, req->bssid,
5461 0);
5462 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005463
5464 if (0 > status)
5465 {
5466 //ReEnable BMPS if disabled
5467 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5468 (NULL != pHddCtx))
5469 {
5470 //ReEnable Bmps and Imps back
5471 hdd_enable_bmps_imps(pHddCtx);
5472 }
5473
5474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5475 return status;
5476 }
5477 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5478 EXIT();
5479 return status;
5480}
5481
5482
5483/*
5484 * FUNCTION: wlan_hdd_cfg80211_disconnect
5485 * This function is used to issue a disconnect request to SME
5486 */
5487static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5488 struct net_device *dev,
5489 u16 reason
5490 )
5491{
5492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5493 tCsrRoamProfile *pRoamProfile =
5494 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5495 int status = 0;
5496 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005497#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005498 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005499 tANI_U8 staIdx;
5500#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005501
5502 ENTER();
5503
5504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5505 __func__,pAdapter->device_mode);
5506
5507 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5508 __func__, reason);
5509
5510 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5511 {
5512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5513 "%s:LOGP in Progress. Ignore!!!",__func__);
5514 return -EAGAIN;
5515 }
5516 if (NULL != pRoamProfile)
5517 {
5518 /*issue disconnect request to SME, if station is in connected state*/
5519 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5520 {
5521 eCsrRoamDisconnectReason reasonCode =
5522 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5523 switch(reason)
5524 {
5525 case WLAN_REASON_MIC_FAILURE:
5526 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5527 break;
5528
5529 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5530 case WLAN_REASON_DISASSOC_AP_BUSY:
5531 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5532 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5533 break;
5534
5535 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5536 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5537 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5538 break;
5539
5540 case WLAN_REASON_DEAUTH_LEAVING:
5541 default:
5542 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5543 break;
5544 }
5545 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5546 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5547 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5548
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005549#ifdef FEATURE_WLAN_TDLS
5550 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005551 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005552 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005553 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5554 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005555 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005556 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005557 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005558 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005559 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005560 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005561 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005562 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005563 pAdapter->sessionId,
5564 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005565 }
5566 }
5567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 /*issue disconnect*/
5569 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5570 pAdapter->sessionId, reasonCode);
5571
5572 if ( 0 != status)
5573 {
5574 hddLog(VOS_TRACE_LEVEL_ERROR,
5575 "%s csrRoamDisconnect failure, returned %d \n",
5576 __func__, (int)status );
5577 return -EINVAL;
5578 }
5579
5580 wait_for_completion_interruptible_timeout(
5581 &pAdapter->disconnect_comp_var,
5582 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5583
5584
5585 /*stop tx queues*/
5586 netif_tx_disable(dev);
5587 netif_carrier_off(dev);
5588 }
5589 }
5590 else
5591 {
5592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5593 }
5594
5595 return status;
5596}
5597
5598/*
5599 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5600 * This function is used to initialize the security
5601 * settings in IBSS mode.
5602 */
5603static int wlan_hdd_cfg80211_set_privacy_ibss(
5604 hdd_adapter_t *pAdapter,
5605 struct cfg80211_ibss_params *params
5606 )
5607{
5608 int status = 0;
5609 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5610 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5611 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5612
5613 ENTER();
5614
5615 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5616
5617 if (params->ie_len && ( NULL != params->ie) )
5618 {
5619 if (WLAN_EID_RSN == params->ie[0])
5620 {
5621 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5622 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5623 }
5624 else
5625 {
5626 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5627 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5628 }
5629 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5630
5631 if (0 > status)
5632 {
5633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5634 __func__);
5635 return status;
5636 }
5637 }
5638
5639 pWextState->roamProfile.AuthType.authType[0] =
5640 pHddStaCtx->conn_info.authType =
5641 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5642
5643 if (params->privacy)
5644 {
5645 /* Security enabled IBSS, At this time there is no information available
5646 * about the security paramters, so initialise the encryption type to
5647 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5648 * The correct security parameters will be updated later in
5649 * wlan_hdd_cfg80211_add_key */
5650 /* Hal expects encryption type to be set inorder
5651 *enable privacy bit in beacons */
5652
5653 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5654 }
5655
5656 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5657 pWextState->roamProfile.EncryptionType.numEntries = 1;
5658 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5659
5660 return status;
5661}
5662
5663/*
5664 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5665 * This function is used to create/join an IBSS
5666 */
5667static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5668 struct net_device *dev,
5669 struct cfg80211_ibss_params *params
5670 )
5671{
5672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5673 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5674 tCsrRoamProfile *pRoamProfile;
5675 int status;
5676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5677
5678 ENTER();
5679
5680 hddLog(VOS_TRACE_LEVEL_INFO,
5681 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5682
5683 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5684 {
5685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5686 "%s:LOGP in Progress. Ignore!!!", __func__);
5687 return -EAGAIN;
5688 }
5689
5690 if (NULL == pWextState)
5691 {
5692 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5693 __func__);
5694 return -EIO;
5695 }
5696
5697 pRoamProfile = &pWextState->roamProfile;
5698
5699 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5700 {
5701 hddLog (VOS_TRACE_LEVEL_ERROR,
5702 "%s Interface type is not set to IBSS \n", __func__);
5703 return -EINVAL;
5704 }
5705
5706 /* Set Channel */
5707 if (NULL != params->channel)
5708 {
5709 u8 channelNum;
5710 if (IEEE80211_BAND_5GHZ == params->channel->band)
5711 {
5712 hddLog(VOS_TRACE_LEVEL_ERROR,
5713 "%s: IBSS join is called with unsupported band %d",
5714 __func__, params->channel->band);
5715 return -EOPNOTSUPP;
5716 }
5717
5718 /* Get channel number */
5719 channelNum =
5720 ieee80211_frequency_to_channel(params->channel->center_freq);
5721
5722 /*TODO: use macro*/
5723 if (14 >= channelNum)
5724 {
5725 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5726 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5727 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5728 int indx;
5729
5730 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5731 validChan, &numChans))
5732 {
5733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5734 __func__);
5735 return -EOPNOTSUPP;
5736 }
5737
5738 for (indx = 0; indx < numChans; indx++)
5739 {
5740 if (channelNum == validChan[indx])
5741 {
5742 break;
5743 }
5744 }
5745 if (indx >= numChans)
5746 {
5747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5748 __func__, channelNum);
5749 return -EINVAL;
5750 }
5751 /* Set the Operational Channel */
5752 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5753 channelNum);
5754 pRoamProfile->ChannelInfo.numOfChannels = 1;
5755 pHddStaCtx->conn_info.operationChannel = channelNum;
5756 pRoamProfile->ChannelInfo.ChannelList =
5757 &pHddStaCtx->conn_info.operationChannel;
5758 }
5759 else
5760 {
5761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5762 __func__, channelNum);
5763 return -EINVAL;
5764 }
5765 }
5766
5767 /* Initialize security parameters */
5768 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5769 if (status < 0)
5770 {
5771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5772 __func__);
5773 return status;
5774 }
5775
5776 /* Issue connect start */
5777 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005778 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005779
5780 if (0 > status)
5781 {
5782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5783 return status;
5784 }
5785
5786 return 0;
5787}
5788
5789/*
5790 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5791 * This function is used to leave an IBSS
5792 */
5793static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5794 struct net_device *dev
5795 )
5796{
5797 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5798 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5799 tCsrRoamProfile *pRoamProfile;
5800
5801 ENTER();
5802
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005803 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5804 {
5805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5806 "%s:LOGP in Progress. Ignore!!!", __func__);
5807 return -EAGAIN;
5808 }
5809
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5811 if (NULL == pWextState)
5812 {
5813 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5814 __func__);
5815 return -EIO;
5816 }
5817
5818 pRoamProfile = &pWextState->roamProfile;
5819
5820 /* Issue disconnect only if interface type is set to IBSS */
5821 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5822 {
5823 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5824 __func__);
5825 return -EINVAL;
5826 }
5827
5828 /* Issue Disconnect request */
5829 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5830 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5831 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5832
5833 return 0;
5834}
5835
5836/*
5837 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5838 * This function is used to set the phy parameters
5839 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5840 */
5841static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5842 u32 changed)
5843{
5844 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5845 tHalHandle hHal = pHddCtx->hHal;
5846
5847 ENTER();
5848
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005849 if ( pHddCtx->isLogpInProgress )
5850 {
5851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5852 "%s:LOGP in Progress. Ignore!!!", __func__);
5853 return -EAGAIN;
5854 }
5855
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5857 {
5858 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5859 WNI_CFG_RTS_THRESHOLD_STAMAX :
5860 wiphy->rts_threshold;
5861
5862 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5863 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5864 {
5865 hddLog(VOS_TRACE_LEVEL_ERROR,
5866 "%s: Invalid RTS Threshold value %hu",
5867 __func__, rts_threshold);
5868 return -EINVAL;
5869 }
5870
5871 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5872 rts_threshold, ccmCfgSetCallback,
5873 eANI_BOOLEAN_TRUE))
5874 {
5875 hddLog(VOS_TRACE_LEVEL_ERROR,
5876 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5877 __func__, rts_threshold);
5878 return -EIO;
5879 }
5880
5881 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5882 rts_threshold);
5883 }
5884
5885 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5886 {
5887 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5888 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5889 wiphy->frag_threshold;
5890
5891 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5892 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5893 {
5894 hddLog(VOS_TRACE_LEVEL_ERROR,
5895 "%s: Invalid frag_threshold value %hu", __func__,
5896 frag_threshold);
5897 return -EINVAL;
5898 }
5899
5900 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5901 frag_threshold, ccmCfgSetCallback,
5902 eANI_BOOLEAN_TRUE))
5903 {
5904 hddLog(VOS_TRACE_LEVEL_ERROR,
5905 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5906 __func__, frag_threshold);
5907 return -EIO;
5908 }
5909
5910 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5911 frag_threshold);
5912 }
5913
5914 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5915 || (changed & WIPHY_PARAM_RETRY_LONG))
5916 {
5917 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5918 wiphy->retry_short :
5919 wiphy->retry_long;
5920
5921 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5922 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5923 {
5924 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5925 __func__, retry_value);
5926 return -EINVAL;
5927 }
5928
5929 if (changed & WIPHY_PARAM_RETRY_SHORT)
5930 {
5931 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5932 retry_value, ccmCfgSetCallback,
5933 eANI_BOOLEAN_TRUE))
5934 {
5935 hddLog(VOS_TRACE_LEVEL_ERROR,
5936 "%s: ccmCfgSetInt failed for long retry count %hu",
5937 __func__, retry_value);
5938 return -EIO;
5939 }
5940 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5941 __func__, retry_value);
5942 }
5943 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5944 {
5945 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5946 retry_value, ccmCfgSetCallback,
5947 eANI_BOOLEAN_TRUE))
5948 {
5949 hddLog(VOS_TRACE_LEVEL_ERROR,
5950 "%s: ccmCfgSetInt failed for short retry count %hu",
5951 __func__, retry_value);
5952 return -EIO;
5953 }
5954 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5955 __func__, retry_value);
5956 }
5957 }
5958
5959 return 0;
5960}
5961
5962/*
5963 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5964 * This function is used to set the txpower
5965 */
5966static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5967#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5968 enum tx_power_setting type,
5969#else
5970 enum nl80211_tx_power_setting type,
5971#endif
5972 int dbm)
5973{
5974 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5975 tHalHandle hHal = pHddCtx->hHal;
5976 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5977 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5978
5979 ENTER();
5980
5981 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5982 dbm, ccmCfgSetCallback,
5983 eANI_BOOLEAN_TRUE))
5984 {
5985 hddLog(VOS_TRACE_LEVEL_ERROR,
5986 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5987 return -EIO;
5988 }
5989
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005990 if ( pHddCtx->isLogpInProgress )
5991 {
5992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5993 "%s:LOGP in Progress. Ignore!!!", __func__);
5994 return -EAGAIN;
5995 }
5996
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5998 dbm);
5999
6000 switch(type)
6001 {
6002 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6003 /* Fall through */
6004 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6005 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6006 {
6007 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6008 __func__);
6009 return -EIO;
6010 }
6011 break;
6012 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
6013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
6014 __func__);
6015 return -EOPNOTSUPP;
6016 break;
6017 default:
6018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6019 __func__, type);
6020 return -EIO;
6021 }
6022
6023 return 0;
6024}
6025
6026/*
6027 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6028 * This function is used to read the txpower
6029 */
6030static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6031{
6032
6033 hdd_adapter_t *pAdapter;
6034 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6035
Jeff Johnsone7245742012-09-05 17:12:55 -07006036 ENTER();
6037
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 if (NULL == pHddCtx)
6039 {
6040 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6041 *dbm = 0;
6042 return -ENOENT;
6043 }
6044
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006045 if ( pHddCtx->isLogpInProgress )
6046 {
6047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6048 "%s:LOGP in Progress. Ignore!!!", __func__);
6049 return -EAGAIN;
6050 }
6051
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6053 if (NULL == pAdapter)
6054 {
6055 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6056 return -ENOENT;
6057 }
6058
6059 wlan_hdd_get_classAstats(pAdapter);
6060 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6061
Jeff Johnsone7245742012-09-05 17:12:55 -07006062 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 return 0;
6064}
6065
6066static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6067 u8* mac, struct station_info *sinfo)
6068{
6069 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6070 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6071 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6072 tANI_U8 rate_flags;
6073
6074 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6075 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006076
6077 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6078 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6079 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6080 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6081 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6082 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6083 tANI_U16 maxRate = 0;
6084 tANI_U16 myRate;
6085 tANI_U16 currentRate = 0;
6086 tANI_U8 maxSpeedMCS = 0;
6087 tANI_U8 maxMCSIdx = 0;
6088 tANI_U8 rateFlag = 1;
6089 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006090 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006091
Jeff Johnsone7245742012-09-05 17:12:55 -07006092 ENTER();
6093
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6095 (0 == ssidlen))
6096 {
6097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6098 " Invalid ssidlen, %d", __func__, ssidlen);
6099 /*To keep GUI happy*/
6100 return 0;
6101 }
6102
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006103 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6104 {
6105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6106 "%s:LOGP in Progress. Ignore!!!", __func__);
6107 return -EAGAIN;
6108 }
6109
Jeff Johnson295189b2012-06-20 16:38:30 -07006110 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6111 sinfo->filled |= STATION_INFO_SIGNAL;
6112
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006113 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6115
6116 //convert to the UI units of 100kbps
6117 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6118
6119#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006120 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 -07006121 sinfo->signal,
6122 pCfg->reportMaxLinkSpeed,
6123 myRate,
6124 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006125 (int) pCfg->linkSpeedRssiMid,
6126 (int) pCfg->linkSpeedRssiLow,
6127 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006128#endif //LINKSPEED_DEBUG_ENABLED
6129
6130 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6131 {
6132 // we do not want to necessarily report the current speed
6133 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6134 {
6135 // report the max possible speed
6136 rssidx = 0;
6137 }
6138 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6139 {
6140 // report the max possible speed with RSSI scaling
6141 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6142 {
6143 // report the max possible speed
6144 rssidx = 0;
6145 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006146 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 {
6148 // report middle speed
6149 rssidx = 1;
6150 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006151 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6152 {
6153 // report middle speed
6154 rssidx = 2;
6155 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 else
6157 {
6158 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006159 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 }
6161 }
6162 else
6163 {
6164 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6165 hddLog(VOS_TRACE_LEVEL_ERROR,
6166 "%s: Invalid value for reportMaxLinkSpeed: %u",
6167 __func__, pCfg->reportMaxLinkSpeed);
6168 rssidx = 0;
6169 }
6170
6171 maxRate = 0;
6172
6173 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306174 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6175 OperationalRates, &ORLeng))
6176 {
6177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6178 /*To keep GUI happy*/
6179 return 0;
6180 }
6181
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 for (i = 0; i < ORLeng; i++)
6183 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006184 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 {
6186 /* Validate Rate Set */
6187 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6188 {
6189 currentRate = supported_data_rate[j].supported_rate[rssidx];
6190 break;
6191 }
6192 }
6193 /* Update MAX rate */
6194 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6195 }
6196
6197 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306198 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6199 ExtendedRates, &ERLeng))
6200 {
6201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6202 /*To keep GUI happy*/
6203 return 0;
6204 }
6205
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 for (i = 0; i < ERLeng; i++)
6207 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006208 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 {
6210 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6211 {
6212 currentRate = supported_data_rate[j].supported_rate[rssidx];
6213 break;
6214 }
6215 }
6216 /* Update MAX rate */
6217 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6218 }
6219
6220 /* Get MCS Rate Set -- but only if we are connected at MCS
6221 rates or if we are always reporting max speed or if we have
6222 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006223 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006224 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306225 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6226 MCSRates, &MCSLeng))
6227 {
6228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6229 /*To keep GUI happy*/
6230 return 0;
6231 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 rateFlag = 0;
6233 if (rate_flags & eHAL_TX_RATE_HT40)
6234 {
6235 rateFlag |= 1;
6236 }
6237 if (rate_flags & eHAL_TX_RATE_SGI)
6238 {
6239 rateFlag |= 2;
6240 }
6241
6242 for (i = 0; i < MCSLeng; i++)
6243 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006244 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6245 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 {
6247 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6248 {
6249 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6250 break;
6251 }
6252 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006253 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 {
6255 maxRate = currentRate;
6256 maxSpeedMCS = 1;
6257 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6258 }
6259 }
6260 }
6261
6262 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006263 if (((maxRate < myRate) && (0 == rssidx)) ||
6264 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 {
6266 maxRate = myRate;
6267 if (rate_flags & eHAL_TX_RATE_LEGACY)
6268 {
6269 maxSpeedMCS = 0;
6270 }
6271 else
6272 {
6273 maxSpeedMCS = 1;
6274 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6275 }
6276 }
6277
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006278 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 {
6280 sinfo->txrate.legacy = maxRate;
6281#ifdef LINKSPEED_DEBUG_ENABLED
6282 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6283#endif //LINKSPEED_DEBUG_ENABLED
6284 }
6285 else
6286 {
6287 sinfo->txrate.mcs = maxMCSIdx;
6288 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6289 if (rate_flags & eHAL_TX_RATE_SGI)
6290 {
6291 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6292 }
6293 if (rate_flags & eHAL_TX_RATE_HT40)
6294 {
6295 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6296 }
6297#ifdef LINKSPEED_DEBUG_ENABLED
6298 pr_info("Reporting MCS rate %d flags %x\n",
6299 sinfo->txrate.mcs,
6300 sinfo->txrate.flags );
6301#endif //LINKSPEED_DEBUG_ENABLED
6302 }
6303 }
6304 else
6305 {
6306 // report current rate instead of max rate
6307
6308 if (rate_flags & eHAL_TX_RATE_LEGACY)
6309 {
6310 //provide to the UI in units of 100kbps
6311 sinfo->txrate.legacy = myRate;
6312#ifdef LINKSPEED_DEBUG_ENABLED
6313 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6314#endif //LINKSPEED_DEBUG_ENABLED
6315 }
6316 else
6317 {
6318 //must be MCS
6319 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6320 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6321 if (rate_flags & eHAL_TX_RATE_SGI)
6322 {
6323 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6324 }
6325 if (rate_flags & eHAL_TX_RATE_HT40)
6326 {
6327 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6328 }
6329#ifdef LINKSPEED_DEBUG_ENABLED
6330 pr_info("Reporting actual MCS rate %d flags %x\n",
6331 sinfo->txrate.mcs,
6332 sinfo->txrate.flags );
6333#endif //LINKSPEED_DEBUG_ENABLED
6334 }
6335 }
6336 sinfo->filled |= STATION_INFO_TX_BITRATE;
6337
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006338 sinfo->tx_packets =
6339 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6340 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6341 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6342 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6343
6344 sinfo->tx_retries =
6345 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6346 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6347 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6348 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6349
6350 sinfo->tx_failed =
6351 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6352 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6353 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6354 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6355
6356 sinfo->filled |=
6357 STATION_INFO_TX_PACKETS |
6358 STATION_INFO_TX_RETRIES |
6359 STATION_INFO_TX_FAILED;
6360
6361 EXIT();
6362 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006363}
6364
6365static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6366 struct net_device *dev, bool mode, v_SINT_t timeout)
6367{
6368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6369 VOS_STATUS vos_status;
6370
Jeff Johnsone7245742012-09-05 17:12:55 -07006371 ENTER();
6372
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 if (NULL == pAdapter)
6374 {
6375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6376 return -ENODEV;
6377 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006378 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6379 {
6380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6381 "%s:LOGP in Progress. Ignore!!!", __func__);
6382 return -EAGAIN;
6383 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006384
6385 /**The get power cmd from the supplicant gets updated by the nl only
6386 *on successful execution of the function call
6387 *we are oppositely mapped w.r.t mode in the driver
6388 **/
6389 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6390
Jeff Johnsone7245742012-09-05 17:12:55 -07006391 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 if (VOS_STATUS_E_FAILURE == vos_status)
6393 {
6394 return -EINVAL;
6395 }
6396 return 0;
6397}
6398
6399
6400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6401static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6402 struct net_device *netdev,
6403 u8 key_index)
6404{
Jeff Johnsone7245742012-09-05 17:12:55 -07006405 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 return 0;
6407}
6408#endif //LINUX_VERSION_CODE
6409
6410#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6411static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6412 struct net_device *dev,
6413 struct ieee80211_txq_params *params)
6414{
Jeff Johnsone7245742012-09-05 17:12:55 -07006415 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 return 0;
6417}
6418#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6419static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6420 struct ieee80211_txq_params *params)
6421{
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 return 0;
6424}
6425#endif //LINUX_VERSION_CODE
6426
6427static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6428 struct net_device *dev, u8 *mac)
6429{
6430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006431 VOS_STATUS vos_status;
6432 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006433
Jeff Johnsone7245742012-09-05 17:12:55 -07006434 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6436 {
6437 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6438 return -EINVAL;
6439 }
6440
6441 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6442 {
6443 hddLog( LOGE,
6444 "%s: Wlan Load/Unload is in progress", __func__);
6445 return -EBUSY;
6446 }
6447
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006448 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6449 {
6450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6451 "%s:LOGP in Progress. Ignore!!!", __func__);
6452 return -EAGAIN;
6453 }
6454
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 )
6458 {
6459 if( NULL == mac )
6460 {
6461 v_U16_t i;
6462 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6463 {
6464 if(pAdapter->aStaInfo[i].isUsed)
6465 {
6466 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6467 hddLog(VOS_TRACE_LEVEL_INFO,
6468 "%s: Delete STA with MAC::"
6469 "%02x:%02x:%02x:%02x:%02x:%02x",
6470 __func__,
6471 macAddr[0], macAddr[1], macAddr[2],
6472 macAddr[3], macAddr[4], macAddr[5]);
6473 hdd_softap_sta_deauth(pAdapter, macAddr);
6474 }
6475 }
6476 }
6477 else
6478 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006479
6480 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6481 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6482 {
6483 hddLog(VOS_TRACE_LEVEL_INFO,
6484 "%s: Skip this DEL STA as this is not used::"
6485 "%02x:%02x:%02x:%02x:%02x:%02x",
6486 __func__,
6487 mac[0], mac[1], mac[2],
6488 mac[3], mac[4], mac[5]);
6489 return -ENOENT;
6490 }
6491
6492 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6493 {
6494 hddLog(VOS_TRACE_LEVEL_INFO,
6495 "%s: Skip this DEL STA as deauth is in progress::"
6496 "%02x:%02x:%02x:%02x:%02x:%02x",
6497 __func__,
6498 mac[0], mac[1], mac[2],
6499 mac[3], mac[4], mac[5]);
6500 return -ENOENT;
6501 }
6502
6503 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6504
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 hddLog(VOS_TRACE_LEVEL_INFO,
6506 "%s: Delete STA with MAC::"
6507 "%02x:%02x:%02x:%02x:%02x:%02x",
6508 __func__,
6509 mac[0], mac[1], mac[2],
6510 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006511
6512 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6513 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6514 {
6515 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6516 hddLog(VOS_TRACE_LEVEL_INFO,
6517 "%s: STA removal failed for ::"
6518 "%02x:%02x:%02x:%02x:%02x:%02x",
6519 __func__,
6520 mac[0], mac[1], mac[2],
6521 mac[3], mac[4], mac[5]);
6522 return -ENOENT;
6523 }
6524
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 }
6526 }
6527
6528 EXIT();
6529
6530 return 0;
6531}
6532
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006533static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6534 struct net_device *dev, u8 *mac, struct station_parameters *params)
6535{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006536 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006537#ifdef FEATURE_WLAN_TDLS
6538 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006539 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006540 mask = params->sta_flags_mask;
6541
6542 set = params->sta_flags_set;
6543
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006544#ifdef WLAN_FEATURE_TDLS_DEBUG
6545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6546 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6547 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6548#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006549
6550 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6551 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006552 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006553 }
6554 }
6555#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006556 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006557}
6558
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006559
6560#ifdef FEATURE_WLAN_LFR
6561static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006562 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006563{
6564#define MAX_PMKSAIDS_IN_CACHE 8
6565 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006566 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006567 tANI_U32 j=0;
6568 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6569 tHalHandle halHandle;
6570 eHalStatus result;
6571 tANI_U8 BSSIDMatched = 0;
6572
Jeff Johnsone7245742012-09-05 17:12:55 -07006573 ENTER();
6574
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006575 // Validate pAdapter
6576 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6577 {
6578 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6579 return -EINVAL;
6580 }
6581
6582 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6583 {
6584 hddLog( LOGE,
6585 "%s: Wlan Load/Unload is in progress", __func__);
6586 return -EBUSY;
6587 }
6588
6589 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6590 {
6591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6592 "%s:LOGP in Progress. Ignore!!!", __func__);
6593 return -EAGAIN;
6594 }
6595
6596 // Retrieve halHandle
6597 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6598
6599 for (j = 0; j < i; j++)
6600 {
6601 if(vos_mem_compare(PMKIDCache[j].BSSID,
6602 pmksa->bssid, WNI_CFG_BSSID_LEN))
6603 {
6604 /* BSSID matched previous entry. Overwrite it. */
6605 BSSIDMatched = 1;
6606 vos_mem_copy(PMKIDCache[j].BSSID,
6607 pmksa->bssid, WNI_CFG_BSSID_LEN);
6608 vos_mem_copy(PMKIDCache[j].PMKID,
6609 pmksa->pmkid,
6610 CSR_RSN_PMKID_SIZE);
6611 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006612 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006613 dump_bssid(pmksa->bssid);
6614 dump_pmkid(halHandle, pmksa->pmkid);
6615 break;
6616 }
6617 }
6618
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006619 /* Check we compared all entries,if then take the first slot now */
6620 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6621
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006622 if (!BSSIDMatched)
6623 {
6624 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6625 vos_mem_copy(PMKIDCache[i].BSSID,
6626 pmksa->bssid, ETHER_ADDR_LEN);
6627 vos_mem_copy(PMKIDCache[i].PMKID,
6628 pmksa->pmkid,
6629 CSR_RSN_PMKID_SIZE);
6630 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006631 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006632 dump_bssid(pmksa->bssid);
6633 dump_pmkid(halHandle, pmksa->pmkid);
6634 // Increment the HDD Local Cache index
6635 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6636 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6637 }
6638
6639
6640 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6641 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006642 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006643 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006644 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006645 // Finally set the PMKSA ID Cache in CSR
6646 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6647 PMKIDCache,
6648 i );
6649 return 0;
6650}
6651
6652
6653static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006654 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006655{
Jeff Johnsone7245742012-09-05 17:12:55 -07006656 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006657 // TODO: Implement this later.
6658 return 0;
6659}
6660
6661static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6662{
Jeff Johnsone7245742012-09-05 17:12:55 -07006663 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006664 // TODO: Implement this later.
6665 return 0;
6666}
6667#endif
6668
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006669#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6670static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6671 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6672{
6673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6674 hdd_station_ctx_t *pHddStaCtx;
6675
6676 if (NULL == pAdapter)
6677 {
6678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6679 return -ENODEV;
6680 }
6681
6682 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6683
6684 // Added for debug on reception of Re-assoc Req.
6685 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6686 {
6687 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6688 ftie->ie_len);
6689 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6690 }
6691
6692#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6693 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6694 ftie->ie_len);
6695#endif
6696
6697 // Pass the received FT IEs to SME
6698 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6699 ftie->ie_len);
6700 return 0;
6701}
6702#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006703
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006704#ifdef FEATURE_WLAN_TDLS
6705static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6706 u8 *peer, u8 action_code, u8 dialog_token,
6707 u16 status_code, const u8 *buf, size_t len)
6708{
6709
6710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6711 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006712 u8 peerMac[6];
6713 VOS_STATUS status;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006714 int ret = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006715 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006716
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006717 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006718 {
6719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6720 "Invalid arguments");
6721 return -EINVAL;
6722 }
6723
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006724 if (pHddCtx->isLogpInProgress)
6725 {
6726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6727 "%s:LOGP in Progress. Ignore!!!", __func__);
6728 return -EBUSY;
6729 }
6730
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006731 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006732 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6733 {
6734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6735 "TDLS Disabled in INI OR not enabled in FW.\
6736 Cannot process TDLS commands \n");
6737 return -ENOTSUPP;
6738 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006739
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006740 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
6741 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006742 if (wlan_hdd_tdls_is_progress(pAdapter, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006743 {
6744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006745 "%s: " MAC_ADDRESS_STR
6746 " TDLS setup is ongoing. Request declined.",
6747 __func__, MAC_ADDR_ARRAY(peer));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006748 return -EPERM;
6749 }
6750 }
6751
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006752 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
6753 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08006754 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006755 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006756 {
6757 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6758 we return error code at 'add_station()'. Hence we have this
6759 check again in addtion to add_station().
6760 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006761 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006762 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6764 "%s: " MAC_ADDRESS_STR
6765 " TDLS Max peer already connected. Request declined.",
6766 __func__, MAC_ADDR_ARRAY(peer));
Lee Hoonkic1262f22013-01-24 21:59:00 -08006767 return -EPERM;
6768 }
6769 else
6770 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006771 /* maximum reached. tweak to send error code to peer and return
6772 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006773 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6775 "%s: " MAC_ADDRESS_STR
6776 " TDLS Max peer already connected send response status %d",
6777 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006778 ret = -EPERM;
6779 /* fall through to send setup resp with failure status
6780 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006781 }
6782 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006783 else
6784 {
6785 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006786 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006787 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
6788 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6790 "%s:" MAC_ADDRESS_STR " already connected. Request declined.",
6791 __func__, MAC_ADDR_ARRAY(peer));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006792 return -EPERM;
6793 }
6794 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006795 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006796 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006797
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006798#ifdef WLAN_FEATURE_TDLS_DEBUG
6799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006800 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
6801 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
6802 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006803#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006804
Hoonki Leea34dd892013-02-05 22:56:02 -08006805 /*Except teardown responder will not be used so just make 0*/
6806 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006807 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08006808 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006809 responder = wlan_hdd_tdls_get_responder(pAdapter, peerMac);
6810 if(-1 == responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08006811 {
6812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006813 "%s: " MAC_ADDRESS_STR " peer doesn't exist dialog_token %d status %d, len = %d",
6814 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
Hoonki Leea34dd892013-02-05 22:56:02 -08006815 dialog_token, status_code, len);
6816 return -EPERM;
6817 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006818 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006819
Pervinder Singhb4638422013-03-04 22:51:36 -08006820 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006821 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006822 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_CONNECTING);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006823
6824 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
6825
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006826 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006827 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006828
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006829 if (VOS_STATUS_SUCCESS != status)
6830 {
6831 if(ret == 0 && /* if failure, don't need to set the progress bit */
6832 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006833 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006834
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6836 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006837 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006838 }
6839
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006840 /* not block discovery request, as it is called from timer callback */
6841 if (SIR_MAC_TDLS_DIS_REQ != action_code)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006842 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006843 long rc;
6844
6845 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006846 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006847
Pervinder Singhb4638422013-03-04 22:51:36 -08006848 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006849 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006850 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006851 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006852 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006853
6854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pervinder Singhb4638422013-03-04 22:51:36 -08006855 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
6856 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006857 return -EPERM;
6858 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006859 }
6860
6861 if (ret)
6862 return ret;
6863
Hoonki Leea34dd892013-02-05 22:56:02 -08006864 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6865 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006866 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006867 }
6868 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6869 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006870 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006871 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006872
6873 return 0;
6874}
6875
6876static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6877 u8 *peer, enum nl80211_tdls_operation oper)
6878{
6879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6880 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006881#ifdef WLAN_FEATURE_TDLS_DEBUG
6882 const char *tdls_oper_str[]= {
6883 "NL80211_TDLS_DISCOVERY_REQ",
6884 "NL80211_TDLS_SETUP",
6885 "NL80211_TDLS_TEARDOWN",
6886 "NL80211_TDLS_ENABLE_LINK",
6887 "NL80211_TDLS_DISABLE_LINK",
6888 "NL80211_TDLS_UNKONW_OPER"};
6889#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006890
6891 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6892 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006894 "Invalid arguments");
6895 return -EINVAL;
6896 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006897
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006898 if (pHddCtx->isLogpInProgress)
6899 {
6900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6901 "%s:LOGP in Progress. Ignore!!!", __func__);
6902 return -EBUSY;
6903 }
6904
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006905#ifdef WLAN_FEATURE_TDLS_DEBUG
6906 if((int)oper > 4)
6907 oper = 5;
6908
6909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006910 "%s: " MAC_ADDRESS_STR " %d (%s) ", "tdls_oper",
6911 MAC_ADDR_ARRAY(peer), (int)oper,
6912 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006913#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006914
6915 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006916 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006917 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006919 "TDLS Disabled in INI OR not enabled in FW.\
6920 Cannot process TDLS commands \n");
6921 return -ENOTSUPP;
6922 }
6923
6924 switch (oper) {
6925 case NL80211_TDLS_ENABLE_LINK:
6926 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006927 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006928 VOS_STATUS status;
6929
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006930 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006931
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006932 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6933 "%s: TDLS_LINK_ENABLE " MAC_ADDRESS_STR,
6934 __func__, MAC_ADDR_ARRAY(peer));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006935
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006936 if ( NULL == pTdlsPeer ) {
6937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer "
6938 MAC_ADDRESS_STR " failed",
6939 __func__, MAC_ADDR_ARRAY(peer));
6940 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006941 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006942
6943 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
6944 {
6945 /* start TDLS client registration with TL */
6946 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
6947 wlan_hdd_tdls_increment_peer_count(pAdapter);
6948 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
6949 wlan_hdd_tdls_check_bmps(pAdapter);
6950 }
6951
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006952 }
6953 break;
6954 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006955 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006956 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006957
6958 if(NULL != curr_peer)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006959 {
6960 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6961 pAdapter->sessionId, peer );
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006962 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08006963 }
6964 else
6965 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6967 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08006968 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006969 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006970 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006971 case NL80211_TDLS_TEARDOWN:
6972 case NL80211_TDLS_SETUP:
6973 case NL80211_TDLS_DISCOVERY_REQ:
6974 /* We don't support in-driver setup/teardown/discovery */
6975 return -ENOTSUPP;
6976 default:
6977 return -ENOTSUPP;
6978 }
6979 return 0;
6980}
Chilam NG571c65a2013-01-19 12:27:36 +05306981
6982int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6983 struct net_device *dev, u8 *peer)
6984{
6985 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6986 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6987
6988 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6989 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6990}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006991#endif
6992
Jeff Johnson295189b2012-06-20 16:38:30 -07006993/* cfg80211_ops */
6994static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6995{
6996 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6997 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6998 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6999 .change_station = wlan_hdd_change_station,
7000#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7001 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7002 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7003 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007004#else
7005 .start_ap = wlan_hdd_cfg80211_start_ap,
7006 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7007 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007008#endif
7009 .change_bss = wlan_hdd_cfg80211_change_bss,
7010 .add_key = wlan_hdd_cfg80211_add_key,
7011 .get_key = wlan_hdd_cfg80211_get_key,
7012 .del_key = wlan_hdd_cfg80211_del_key,
7013 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007014#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007016#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 .scan = wlan_hdd_cfg80211_scan,
7018 .connect = wlan_hdd_cfg80211_connect,
7019 .disconnect = wlan_hdd_cfg80211_disconnect,
7020 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7021 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7022 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7023 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7024 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7026 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7027 .mgmt_tx = wlan_hdd_action,
7028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7029 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7030 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7031 .set_txq_params = wlan_hdd_set_txq_params,
7032#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 .get_station = wlan_hdd_cfg80211_get_station,
7034 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7035 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007036 .add_station = wlan_hdd_cfg80211_add_station,
7037#ifdef FEATURE_WLAN_LFR
7038 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7039 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7040 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7041#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007042#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7043 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7044#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007045#ifdef FEATURE_WLAN_TDLS
7046 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7047 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007049};
7050