blob: 1e37eb9e79488719a4867e767f5e1f53ff3fbf42 [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 {
1429 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1430
1431 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
1432 {
1433 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1434
1435 /* If auto channel selection is configured as enable/ 1 then ignore
1436 channel set by supplicant
1437 */
1438 if ( cfg_param->apAutoChannelSelection )
1439 {
1440 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
1441
1442 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1443 "%s: set channel to auto channel (0) for device mode =%d",
1444 __func__, pAdapter->device_mode);
1445 }
1446 }
1447 }
1448 else
1449 {
1450 hddLog(VOS_TRACE_LEVEL_FATAL,
1451 "%s: Invalid device mode failed to set valid channel", __func__);
1452 return -EINVAL;
1453 }
1454 EXIT();
1455 return 0;
1456}
1457
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301458/*
1459 * FUNCTION: wlan_hdd_select_cbmode
1460 * called by wlan_hdd_cfg80211_start_bss() and
1461 * This function selects the cbmode based on primary channel
1462 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001463VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301464{
1465 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001466 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1467 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1468
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301469 if(
1470#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001471 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1472 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301473#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001474 SapHw_mode != eSAP_DOT11_MODE_11n &&
1475 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301476 )
1477 {
1478 return VOS_STATUS_SUCCESS;
1479 }
1480
1481 if (!pConfigIni->nChannelBondingMode5GHz) {
1482 return VOS_STATUS_SUCCESS;
1483 }
1484
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001485 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301486 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1487
1488 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1489
1490#ifdef WLAN_FEATURE_11AC
1491
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001492 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1493 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301494 {
1495 if ( channel== 36 || channel == 52 || channel == 100 ||
1496 channel == 116 || channel == 149 )
1497 {
1498 smeConfig.csrConfig.channelBondingMode5GHz =
1499 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1500 }
1501 else if ( channel == 40 || channel == 56 || channel == 104 ||
1502 channel == 120 || channel == 153 )
1503 {
1504 smeConfig.csrConfig.channelBondingMode5GHz =
1505 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1506 }
1507 else if ( channel == 44 || channel == 60 || channel == 108 ||
1508 channel == 124 || channel == 157 )
1509 {
1510 smeConfig.csrConfig.channelBondingMode5GHz =
1511 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1512 }
1513 else if ( channel == 48 || channel == 64 || channel == 112 ||
1514 channel == 128 || channel == 161 )
1515 {
1516 smeConfig.csrConfig.channelBondingMode5GHz =
1517 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1518 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001519 else if ( channel == 165 )
1520 {
1521 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1522 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301523 }
1524#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001525 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1526 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301527 {
1528 if ( channel== 40 || channel == 48 || channel == 56 ||
1529 channel == 64 || channel == 104 || channel == 112 ||
1530 channel == 120 || channel == 128 || channel == 136 ||
1531 channel == 144 || channel == 153 || channel == 161 )
1532 {
1533 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1534 }
1535 else if ( channel== 36 || channel == 44 || channel == 52 ||
1536 channel == 60 || channel == 100 || channel == 108 ||
1537 channel == 116 || channel == 124 || channel == 132 ||
1538 channel == 140 || channel == 149 || channel == 157 )
1539 {
1540 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1541 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001542 else if ( channel == 165 )
1543 {
1544 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1545 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301546 }
1547 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1548
1549 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1550 return VOS_STATUS_SUCCESS;
1551}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001552
Jeff Johnson295189b2012-06-20 16:38:30 -07001553#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1554static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1555 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001556#else
1557static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1558 struct cfg80211_beacon_data *params,
1559 const u8 *ssid, size_t ssid_len,
1560 enum nl80211_hidden_ssid hidden_ssid)
1561#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001562{
1563 tsap_Config_t *pConfig;
1564 beacon_data_t *pBeacon = NULL;
1565 struct ieee80211_mgmt *pMgmt_frame;
1566 v_U8_t *pIe=NULL;
1567 v_U16_t capab_info;
1568 eCsrAuthType RSNAuthType;
1569 eCsrEncryptionType RSNEncryptType;
1570 eCsrEncryptionType mcRSNEncryptType;
1571 int status = VOS_STATUS_SUCCESS;
1572 tpWLAN_SAPEventCB pSapEventCallback;
1573 hdd_hostapd_state_t *pHostapdState;
1574 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1575 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301576 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001577 struct qc_mac_acl_entry *acl_entry = NULL;
1578 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001579 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001580
1581 ENTER();
1582
1583 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1584
1585 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1586
1587 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1588
1589 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1590
1591 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1592
1593 //channel is already set in the set_channel Call back
1594 //pConfig->channel = pCommitConfig->channel;
1595
1596 /*Protection parameter to enable or disable*/
1597 pConfig->protEnabled =
1598 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1599
1600 pConfig->dtim_period = pBeacon->dtim_period;
1601
1602 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1603 pConfig->dtim_period);
1604
1605
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001606 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001607 {
1608 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001609 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001610 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001612 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001613 pConfig->ieee80211d = 1;
1614 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1615 sme_setRegInfo(hHal, pConfig->countryCode);
1616 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001618 else
1619 {
1620 pConfig->ieee80211d = 0;
1621 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301622 /*
1623 * If auto channel is configured i.e. channel is 0,
1624 * so skip channel validation.
1625 */
1626 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1627 {
1628 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1629 {
1630 hddLog(VOS_TRACE_LEVEL_ERROR,
1631 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1632 return -EINVAL;
1633 }
1634 }
1635 else
1636 {
1637 if(1 != pHddCtx->is_dynamic_channel_range_set)
1638 {
1639 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1640 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1641 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1642 }
1643 pHddCtx->is_dynamic_channel_range_set = 0;
1644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001646 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 {
1648 pConfig->ieee80211d = 0;
1649 }
1650 pConfig->authType = eSAP_AUTO_SWITCH;
1651
1652 capab_info = pMgmt_frame->u.beacon.capab_info;
1653
1654 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1655 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1656
1657 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1658
1659 /*Set wps station to configured*/
1660 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1661
1662 if(pIe)
1663 {
1664 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1665 {
1666 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1667 return -EINVAL;
1668 }
1669 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1670 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001671 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 /* Check 15 bit of WPS IE as it contain information for wps state
1673 * WPS state
1674 */
1675 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1676 {
1677 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1678 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1679 {
1680 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1681 }
1682 }
1683 }
1684 else
1685 {
1686 pConfig->wps_state = SAP_WPS_DISABLED;
1687 }
1688 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1689
1690 pConfig->RSNWPAReqIELength = 0;
1691 pConfig->pRSNWPAReqIE = NULL;
1692 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1693 WLAN_EID_RSN);
1694 if(pIe && pIe[1])
1695 {
1696 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1697 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1698 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1699 /* The actual processing may eventually be more extensive than
1700 * this. Right now, just consume any PMKIDs that are sent in
1701 * by the app.
1702 * */
1703 status = hdd_softap_unpackIE(
1704 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1705 &RSNEncryptType,
1706 &mcRSNEncryptType,
1707 &RSNAuthType,
1708 pConfig->pRSNWPAReqIE[1]+2,
1709 pConfig->pRSNWPAReqIE );
1710
1711 if( VOS_STATUS_SUCCESS == status )
1712 {
1713 /* Now copy over all the security attributes you have
1714 * parsed out
1715 * */
1716 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1717 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1718 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1719 = RSNEncryptType;
1720 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1721 "EncryptionType = %d mcEncryptionType = %d\n"),
1722 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1723 }
1724 }
1725
1726 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1727 pBeacon->tail, pBeacon->tail_len);
1728
1729 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1730 {
1731 if (pConfig->pRSNWPAReqIE)
1732 {
1733 /*Mixed mode WPA/WPA2*/
1734 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1735 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1736 }
1737 else
1738 {
1739 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1740 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1741 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1742 status = hdd_softap_unpackIE(
1743 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1744 &RSNEncryptType,
1745 &mcRSNEncryptType,
1746 &RSNAuthType,
1747 pConfig->pRSNWPAReqIE[1]+2,
1748 pConfig->pRSNWPAReqIE );
1749
1750 if( VOS_STATUS_SUCCESS == status )
1751 {
1752 /* Now copy over all the security attributes you have
1753 * parsed out
1754 * */
1755 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1756 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1757 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1758 = RSNEncryptType;
1759 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1760 "EncryptionType = %d mcEncryptionType = %d\n"),
1761 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1762 }
1763 }
1764 }
1765
1766 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1767
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001768#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001769 if (params->ssid != NULL)
1770 {
1771 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1772 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1773 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1774 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1775 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001776#else
1777 if (ssid != NULL)
1778 {
1779 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1780 pConfig->SSIDinfo.ssid.length = ssid_len;
1781 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1782 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1783 }
1784#endif
1785
Jeff Johnson295189b2012-06-20 16:38:30 -07001786 vos_mem_copy(pConfig->self_macaddr.bytes,
1787 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1788
1789 /* default value */
1790 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1791 pConfig->num_accept_mac = 0;
1792 pConfig->num_deny_mac = 0;
1793
1794 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1795 pBeacon->tail, pBeacon->tail_len);
1796
1797 /* pIe for black list is following form:
1798 type : 1 byte
1799 length : 1 byte
1800 OUI : 4 bytes
1801 acl type : 1 byte
1802 no of mac addr in black list: 1 byte
1803 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1804 */
1805 if ((pIe != NULL) && (pIe[1] != 0))
1806 {
1807 pConfig->SapMacaddr_acl = pIe[6];
1808 pConfig->num_deny_mac = pIe[7];
1809 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1810 pIe[6], pIe[7]);
1811 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1812 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1813 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1814 for (i = 0; i < pConfig->num_deny_mac; i++)
1815 {
1816 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1817 acl_entry++;
1818 }
1819 }
1820 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1821 pBeacon->tail, pBeacon->tail_len);
1822
1823 /* pIe for white list is following form:
1824 type : 1 byte
1825 length : 1 byte
1826 OUI : 4 bytes
1827 acl type : 1 byte
1828 no of mac addr in white list: 1 byte
1829 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1830 */
1831 if ((pIe != NULL) && (pIe[1] != 0))
1832 {
1833 pConfig->SapMacaddr_acl = pIe[6];
1834 pConfig->num_accept_mac = pIe[7];
1835 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1836 pIe[6], pIe[7]);
1837 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1838 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1839 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1840 for (i = 0; i < pConfig->num_accept_mac; i++)
1841 {
1842 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1843 acl_entry++;
1844 }
1845 }
1846 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1847
Jeff Johnsone7245742012-09-05 17:12:55 -07001848#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001849 /* Overwrite the hostapd setting for HW mode only for 11ac.
1850 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1851 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1852 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1853 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1854 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1855 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1856 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001857 {
1858 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1859 }
1860#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301861
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001862 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1863 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 // ht_capab is not what the name conveys,this is used for protection bitmap
1865 pConfig->ht_capab =
1866 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1867
1868 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1869 {
1870 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1871 return -EINVAL;
1872 }
1873
1874 //Uapsd Enabled Bit
1875 pConfig->UapsdEnable =
1876 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1877 //Enable OBSS protection
1878 pConfig->obssProtEnabled =
1879 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1880
1881 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1882 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1883 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1884 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1885 (int)pConfig->channel);
1886 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1887 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1888 pConfig->authType);
1889 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1890 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1891 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1892 pConfig->protEnabled, pConfig->obssProtEnabled);
1893
1894 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1895 {
1896 //Bss already started. just return.
1897 //TODO Probably it should update some beacon params.
1898 hddLog( LOGE, "Bss Already started...Ignore the request");
1899 EXIT();
1900 return 0;
1901 }
1902
1903 pConfig->persona = pHostapdAdapter->device_mode;
1904
1905 pSapEventCallback = hdd_hostapd_SAPEventCB;
1906 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1907 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1908 {
1909 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1910 return -EINVAL;
1911 }
1912
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001913 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1915
1916 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1917
1918 if (!VOS_IS_STATUS_SUCCESS(status))
1919 {
1920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1921 ("ERROR: HDD vos wait for single_event failed!!\n"));
1922 VOS_ASSERT(0);
1923 }
1924
1925 //Succesfully started Bss update the state bit.
1926 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1927
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001928#ifdef WLAN_FEATURE_P2P_DEBUG
1929 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1930 {
1931 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1932 {
1933 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1934 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001935 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001936 }
1937 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1938 {
1939 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1940 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001941 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001942 }
1943 }
1944#endif
1945
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 pHostapdState->bCommit = TRUE;
1947 EXIT();
1948
1949 return 0;
1950}
1951
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001952#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001953static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1954 struct net_device *dev,
1955 struct beacon_parameters *params)
1956{
1957 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1958 int status=VOS_STATUS_SUCCESS;
1959
1960 ENTER();
1961
1962 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1963
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001964 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1965 {
1966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1967 "%s:LOGP in Progress. Ignore!!!", __func__);
1968 return -EAGAIN;
1969 }
1970
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 )
1974 {
1975 beacon_data_t *old,*new;
1976
1977 old = pAdapter->sessionCtx.ap.beacon;
1978
1979 if (old)
1980 return -EALREADY;
1981
1982 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1983
1984 if(status != VOS_STATUS_SUCCESS)
1985 {
1986 hddLog(VOS_TRACE_LEVEL_FATAL,
1987 "%s:Error!!! Allocating the new beacon\n",__func__);
1988 return -EINVAL;
1989 }
1990
1991 pAdapter->sessionCtx.ap.beacon = new;
1992
1993 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
1994 }
1995
1996 EXIT();
1997 return status;
1998}
1999
2000static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
2001 struct net_device *dev,
2002 struct beacon_parameters *params)
2003{
2004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2005 int status=VOS_STATUS_SUCCESS;
2006
2007 ENTER();
2008
2009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2010 __func__,pAdapter->device_mode);
2011
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002012 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2013 {
2014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2015 "%s:LOGP in Progress. Ignore!!!", __func__);
2016 return -EAGAIN;
2017 }
2018
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002021 )
2022 {
2023 beacon_data_t *old,*new;
2024
2025 old = pAdapter->sessionCtx.ap.beacon;
2026
2027 if (!old)
2028 return -ENOENT;
2029
2030 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2031
2032 if(status != VOS_STATUS_SUCCESS) {
2033 hddLog(VOS_TRACE_LEVEL_FATAL,
2034 "%s: Error!!! Allocating the new beacon\n",__func__);
2035 return -EINVAL;
2036 }
2037
2038 pAdapter->sessionCtx.ap.beacon = new;
2039
2040 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2041 }
2042
2043 EXIT();
2044 return status;
2045}
2046
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002047#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2048
2049#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002050static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2051 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002052#else
2053static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2054 struct net_device *dev)
2055#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002056{
2057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002058 hdd_context_t *pHddCtx = NULL;
2059 hdd_scaninfo_t *pScanInfo = NULL;
2060 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002061 VOS_STATUS status = 0;
2062
2063 ENTER();
2064
2065 if (NULL == pAdapter)
2066 {
2067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002068 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 return -ENODEV;
2070 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002071 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2072 {
2073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2074 "%s:LOGP in Progress. Ignore!!!", __func__);
2075 return -EAGAIN;
2076 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002077
2078 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2079 if (NULL == pHddCtx)
2080 {
2081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002082 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002083 return -ENODEV;
2084 }
2085
2086 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2087 if (NULL == staAdapter)
2088 {
2089 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2090 if (NULL == staAdapter)
2091 {
2092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002093 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002094 return -ENODEV;
2095 }
2096 }
2097
2098 pScanInfo = &pHddCtx->scan_info;
2099
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2101 {
2102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2103 return -EAGAIN;
2104 }
2105
2106 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2107
2108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2109 __func__,pAdapter->device_mode);
2110
Jeff Johnsone7245742012-09-05 17:12:55 -07002111 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2112 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002113 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002114 hdd_abort_mac_scan(staAdapter->pHddCtx);
2115 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002116 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002117 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2118 if (!status)
2119 {
2120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002121 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002122 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002123 VOS_ASSERT(pScanInfo->mScanPending);
2124 return 0;
2125 }
2126 }
2127
Jeff Johnson295189b2012-06-20 16:38:30 -07002128 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 )
2131 {
2132 beacon_data_t *old;
2133
2134 old = pAdapter->sessionCtx.ap.beacon;
2135
2136 if (!old)
2137 return -ENOENT;
2138
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002140
2141 mutex_lock(&pHddCtx->sap_lock);
2142 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2143 {
2144 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2145 {
2146 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2147
2148 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2149
2150 if (!VOS_IS_STATUS_SUCCESS(status))
2151 {
2152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2153 ("ERROR: HDD vos wait for single_event failed!!\n"));
2154 VOS_ASSERT(0);
2155 }
2156 }
2157 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2158 }
2159 mutex_unlock(&pHddCtx->sap_lock);
2160
2161 if(status != VOS_STATUS_SUCCESS)
2162 {
2163 hddLog(VOS_TRACE_LEVEL_FATAL,
2164 "%s:Error!!! Stopping the BSS\n",__func__);
2165 return -EINVAL;
2166 }
2167
2168 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2169 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2170 ==eHAL_STATUS_FAILURE)
2171 {
2172 hddLog(LOGE,
2173 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2174 }
2175
2176 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2177 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2178 eANI_BOOLEAN_FALSE) )
2179 {
2180 hddLog(LOGE,
2181 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2182 }
2183
2184 // Reset WNI_CFG_PROBE_RSP Flags
2185 wlan_hdd_reset_prob_rspies(pAdapter);
2186
2187 pAdapter->sessionCtx.ap.beacon = NULL;
2188 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002189#ifdef WLAN_FEATURE_P2P_DEBUG
2190 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2191 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2192 {
2193 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2194 "GO got removed");
2195 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2196 }
2197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002198 }
2199 EXIT();
2200 return status;
2201}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002202
2203#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2204
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302205static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2206 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002207 struct cfg80211_ap_settings *params)
2208{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302209 hdd_adapter_t *pAdapter;
2210 hdd_context_t *pHddCtx;
2211 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002212
2213 ENTER();
2214
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302215 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002216 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2218 "%s: Device is Null", __func__);
2219 return -ENODEV;
2220 }
2221
2222 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2223 if (NULL == pAdapter)
2224 {
2225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2226 "%s: HDD adapter is Null", __func__);
2227 return -ENODEV;
2228 }
2229
2230 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2231 {
2232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2233 "%s: HDD adapter magic is invalid", __func__);
2234 return -ENODEV;
2235 }
2236
2237 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2238 if (NULL == pHddCtx)
2239 {
2240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2241 "%s: HDD context is Null", __func__);
2242 return -ENODEV;
2243 }
2244
2245 if (pHddCtx->isLogpInProgress)
2246 {
2247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2248 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002249 return -EAGAIN;
2250 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302251
2252 if (pHddCtx->isLoadUnloadInProgress)
2253 {
2254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2255 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2256 return -EAGAIN;
2257 }
2258
2259 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2260 __func__, pAdapter->device_mode);
2261
2262 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002263 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002264 )
2265 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302266 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002267
2268 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302269
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002270 if (old)
2271 return -EALREADY;
2272
2273 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2274
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302275 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002276 {
2277 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302278 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002279 return -EINVAL;
2280 }
2281 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002282#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2283 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2284#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002285 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2286 params->ssid_len, params->hidden_ssid);
2287 }
2288
2289 EXIT();
2290 return status;
2291}
2292
2293
2294static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2295 struct net_device *dev,
2296 struct cfg80211_beacon_data *params)
2297{
2298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2299 int status=VOS_STATUS_SUCCESS;
2300
2301 ENTER();
2302
2303 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2304 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002305 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2306 {
2307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2308 return -EAGAIN;
2309 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002310
2311 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002312 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002313 )
2314 {
2315 beacon_data_t *old,*new;
2316
2317 old = pAdapter->sessionCtx.ap.beacon;
2318
2319 if (!old)
2320 return -ENOENT;
2321
2322 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2323
2324 if(status != VOS_STATUS_SUCCESS) {
2325 hddLog(VOS_TRACE_LEVEL_FATAL,
2326 "%s: Error!!! Allocating the new beacon\n",__func__);
2327 return -EINVAL;
2328 }
2329
2330 pAdapter->sessionCtx.ap.beacon = new;
2331
2332 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2333 }
2334
2335 EXIT();
2336 return status;
2337}
2338
2339#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2340
Jeff Johnson295189b2012-06-20 16:38:30 -07002341
2342static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2343 struct net_device *dev,
2344 struct bss_parameters *params)
2345{
2346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2347
2348 ENTER();
2349
2350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2351 __func__,pAdapter->device_mode);
2352
2353 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002355 )
2356 {
2357 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2358 * want to update this parameter */
2359 if (-1 != params->ap_isolate)
2360 {
2361 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2362 }
2363 }
2364
2365 EXIT();
2366 return 0;
2367}
2368
2369/*
2370 * FUNCTION: wlan_hdd_cfg80211_change_iface
2371 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2372 */
2373int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2374 struct net_device *ndev,
2375 enum nl80211_iftype type,
2376 u32 *flags,
2377 struct vif_params *params
2378 )
2379{
2380 struct wireless_dev *wdev;
2381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2382 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002383 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 tCsrRoamProfile *pRoamProfile = NULL;
2385 eCsrRoamBssType LastBSSType;
2386 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2387 eMib_dot11DesiredBssType connectedBssType;
2388 VOS_STATUS status;
2389
2390 ENTER();
2391
2392 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2393 {
2394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2395 return -EAGAIN;
2396 }
2397
2398 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2399 __func__, pAdapter->device_mode);
2400
2401 wdev = ndev->ieee80211_ptr;
2402
2403#ifdef WLAN_BTAMP_FEATURE
2404 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2405 (NL80211_IFTYPE_ADHOC == type)||
2406 (NL80211_IFTYPE_AP == type)||
2407 (NL80211_IFTYPE_P2P_GO == type))
2408 {
2409 pHddCtx->isAmpAllowed = VOS_FALSE;
2410 // stop AMP traffic
2411 status = WLANBAP_StopAmp();
2412 if(VOS_STATUS_SUCCESS != status )
2413 {
2414 pHddCtx->isAmpAllowed = VOS_TRUE;
2415 hddLog(VOS_TRACE_LEVEL_FATAL,
2416 "%s: Failed to stop AMP", __func__);
2417 return -EINVAL;
2418 }
2419 }
2420#endif //WLAN_BTAMP_FEATURE
2421 /* Reset the current device mode bit mask*/
2422 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2423
2424 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002425 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002426 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 )
2428 {
2429 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2430 pRoamProfile = &pWextState->roamProfile;
2431 LastBSSType = pRoamProfile->BSSType;
2432
2433 switch (type)
2434 {
2435 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002436 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 hddLog(VOS_TRACE_LEVEL_INFO,
2438 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2439 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002440#ifdef WLAN_FEATURE_11AC
2441 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2442 {
2443 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2444 }
2445#endif
2446 pRoamProfile->phyMode =
2447 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002448 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002449 //Check for sub-string p2p to confirm its a p2p interface
2450 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002451 {
2452 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2453 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2454 }
2455 else
2456 {
2457 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002458 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002460 break;
2461 case NL80211_IFTYPE_ADHOC:
2462 hddLog(VOS_TRACE_LEVEL_INFO,
2463 "%s: setting interface Type to ADHOC", __func__);
2464 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2465 pRoamProfile->phyMode =
2466 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2467 wdev->iftype = type;
2468 break;
2469
2470 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002471 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002472 {
2473 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2474 "%s: setting interface Type to %s", __func__,
2475 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2476
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002477 //Cancel any remain on channel for GO mode
2478 if (NL80211_IFTYPE_P2P_GO == type)
2479 {
2480 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2481 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002482 if (NL80211_IFTYPE_AP == type)
2483 {
2484 /* As Loading WLAN Driver one interface being created for p2p device
2485 * address. This will take one HW STA and the max number of clients
2486 * that can connect to softAP will be reduced by one. so while changing
2487 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2488 * interface as it is not required in SoftAP mode.
2489 */
2490
2491 // Get P2P Adapter
2492 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2493
2494 if (pP2pAdapter)
2495 {
2496 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2497 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2498 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2499 }
2500 }
2501
Jeff Johnson295189b2012-06-20 16:38:30 -07002502 //De-init the adapter.
2503 hdd_stop_adapter( pHddCtx, pAdapter );
2504 hdd_deinit_adapter( pHddCtx, pAdapter );
2505 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2507 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002508
2509 //Disable BMPS and IMPS if enabled
2510 //before starting Go
2511 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2512 {
2513 if(VOS_STATUS_E_FAILURE ==
2514 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2515 {
2516 //Fail to Exit BMPS
2517 VOS_ASSERT(0);
2518 }
2519 }
2520
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002521 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2522 (pConfig->apRandomBssidEnabled))
2523 {
2524 /* To meet Android requirements create a randomized
2525 MAC address of the form 02:1A:11:Fx:xx:xx */
2526 get_random_bytes(&ndev->dev_addr[3], 3);
2527 ndev->dev_addr[0] = 0x02;
2528 ndev->dev_addr[1] = 0x1A;
2529 ndev->dev_addr[2] = 0x11;
2530 ndev->dev_addr[3] |= 0xF0;
2531 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2532 VOS_MAC_ADDR_SIZE);
2533 pr_info("wlan: Generated HotSpot BSSID "
2534 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2535 ndev->dev_addr[0],
2536 ndev->dev_addr[1],
2537 ndev->dev_addr[2],
2538 ndev->dev_addr[3],
2539 ndev->dev_addr[4],
2540 ndev->dev_addr[5]);
2541 }
2542
Jeff Johnson295189b2012-06-20 16:38:30 -07002543 hdd_set_ap_ops( pAdapter->dev );
2544
2545 status = hdd_init_ap_mode(pAdapter);
2546 if(status != VOS_STATUS_SUCCESS)
2547 {
2548 hddLog(VOS_TRACE_LEVEL_FATAL,
2549 "%s: Error initializing the ap mode", __func__);
2550 return -EINVAL;
2551 }
2552 hdd_set_conparam(1);
2553
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 /*interface type changed update in wiphy structure*/
2555 if(wdev)
2556 {
2557 wdev->iftype = type;
2558 pHddCtx->change_iface = type;
2559 }
2560 else
2561 {
2562 hddLog(VOS_TRACE_LEVEL_ERROR,
2563 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2564 return -EINVAL;
2565 }
2566 goto done;
2567 }
2568
2569 default:
2570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2571 __func__);
2572 return -EOPNOTSUPP;
2573 }
2574 }
2575 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002576 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002577 )
2578 {
2579 switch(type)
2580 {
2581 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002582 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002583 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002584 hdd_stop_adapter( pHddCtx, pAdapter );
2585 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002586 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002587 //Check for sub-string p2p to confirm its a p2p interface
2588 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002589 {
2590 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2591 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2592 }
2593 else
2594 {
2595 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002596 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002597 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 hdd_set_conparam(0);
2599 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002600 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2601 hdd_set_station_ops( pAdapter->dev );
2602 status = hdd_init_station_mode( pAdapter );
2603 if( VOS_STATUS_SUCCESS != status )
2604 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002605 /* In case of JB, for P2P-GO, only change interface will be called,
2606 * This is the right place to enable back bmps_imps()
2607 */
2608 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002609 goto done;
2610 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002611 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002612 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002613 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2614 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002615 goto done;
2616 default:
2617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2618 __func__);
2619 return -EOPNOTSUPP;
2620
2621 }
2622
2623 }
2624 else
2625 {
2626 return -EOPNOTSUPP;
2627 }
2628
2629
2630 if(pRoamProfile)
2631 {
2632 if ( LastBSSType != pRoamProfile->BSSType )
2633 {
2634 /*interface type changed update in wiphy structure*/
2635 wdev->iftype = type;
2636
2637 /*the BSS mode changed, We need to issue disconnect
2638 if connected or in IBSS disconnect state*/
2639 if ( hdd_connGetConnectedBssType(
2640 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2641 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2642 {
2643 /*need to issue a disconnect to CSR.*/
2644 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2645 if( eHAL_STATUS_SUCCESS ==
2646 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2647 pAdapter->sessionId,
2648 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2649 {
2650 wait_for_completion_interruptible_timeout(
2651 &pAdapter->disconnect_comp_var,
2652 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2653 }
2654 }
2655 }
2656 }
2657
2658done:
2659 /*set bitmask based on updated value*/
2660 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2661#ifdef WLAN_BTAMP_FEATURE
2662 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2663 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2664 {
2665 //we are ok to do AMP
2666 pHddCtx->isAmpAllowed = VOS_TRUE;
2667 }
2668#endif //WLAN_BTAMP_FEATURE
2669 EXIT();
2670 return 0;
2671}
2672
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002673#ifdef FEATURE_WLAN_TDLS
2674static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2675 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2676{
2677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2678 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2679 VOS_STATUS status;
2680
2681 ENTER();
2682
2683 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
2684 {
2685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2686 "Invalid arguments");
2687 return -EINVAL;
2688 }
2689 if (pHddCtx->isLogpInProgress)
2690 {
2691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2692 "%s:LOGP in Progress. Ignore!!!", __func__);
2693 return -EBUSY;
2694 }
2695
2696 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
2697 FALSE == sme_IsFeatureSupportedByFW(TDLS))
2698 {
2699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2700 "TDLS Disabled in INI OR not enabled in FW.\
2701 Cannot process TDLS commands \n");
2702 return -ENOTSUPP;
2703 }
2704
2705 if (wlan_hdd_tdls_is_progress(pAdapter, mac, TRUE))
2706 {
2707 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2708 "%s: TDLS setup is ongoing. Request declined.",__func__);
2709 return -EPERM;
2710 }
2711
2712 /* first to check if we reached to maximum supported TDLS peer.
2713 TODO: for now, return -EPERM looks working fine,
2714 but need to check if any other errno fit into this category.*/
2715 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2716 {
2717 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2718 "%s: TDLS Max peer already connected. Request declined. \n",
2719 __func__);
2720 return -EPERM;
2721 }
2722 else
2723 {
2724 hddTdlsPeer_t *pTdlsPeer;
2725 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2726 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
2727 {
2728 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2729 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
2730 __func__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
2731 return -EPERM;
2732 }
2733 }
2734
2735 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
2736
2737 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2738
2739 if (!update)
2740 {
2741 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2742 pAdapter->sessionId, mac);
2743 }
2744 else
2745 {
2746 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2747 pAdapter->sessionId, mac, StaParams);
2748 }
2749
2750 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2751 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2752
2753 if (!status)
2754 {
2755 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2756 "%s: timeout waiting for tdls add station indication",
2757 __func__);
2758 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2759 return -EPERM;
2760 }
2761 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2762 {
2763 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2764 "%s: Add Station is unsucessful", __func__);
2765 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2766 return -EPERM;
2767 }
2768
2769 return 0;
2770}
2771#endif
2772
Jeff Johnson295189b2012-06-20 16:38:30 -07002773static int wlan_hdd_change_station(struct wiphy *wiphy,
2774 struct net_device *dev,
2775 u8 *mac,
2776 struct station_parameters *params)
2777{
2778 VOS_STATUS status = VOS_STATUS_SUCCESS;
2779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2780 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002781#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002782 tCsrStaParams StaParams = {0};
2783 u32 set;
2784 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002785#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002786 ENTER();
2787
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002788 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2789 {
2790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s:LOGP in Progress. Ignore!!!", __func__);
2792 return -EAGAIN;
2793 }
2794
Jeff Johnson295189b2012-06-20 16:38:30 -07002795 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2796
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002797#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002798 StaParams.capability = params->capability;
2799 StaParams.uapsd_queues = params->uapsd_queues;
2800 StaParams.max_sp = params->max_sp;
2801
2802 if (0 != params->ext_capab_len)
2803 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2804 sizeof(StaParams.extn_capability));
2805
2806 if (NULL != params->ht_capa)
2807 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
2808
2809 StaParams.supported_rates_len = params->supported_rates_len;
2810
2811 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2812 * The supported_rates array , for all the structures propogating till Add Sta
2813 * to the firmware has to be modified , if the supplicant (ieee80211) is
2814 * modified to send more rates.
2815 */
2816
2817 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2818 */
2819 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2820 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2821
2822 if (0 != StaParams.supported_rates_len) {
2823 int i = 0;
2824 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2825 StaParams.supported_rates_len);
2826 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2827 "Supported Rates with Length %d", StaParams.supported_rates_len);
2828 for (i=0; i < StaParams.supported_rates_len; i++)
2829 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2830 "[%d]: %0x", i, StaParams.supported_rates[i]);
2831 }
2832
2833 if (NULL != params->vht_capa)
2834 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
2835
2836 set = params->sta_flags_set;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002837#endif
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002838
2839 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2840 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002841 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002842 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002843 {
2844 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2845 WLANTL_STA_AUTHENTICATED);
2846
2847 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002848 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002849 return -EINVAL;
2850 }
2851 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002852#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002853 else if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ) {
2854 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2855 if (0 != params->ext_capab_len ) {
2856 /*Define A Macro : TODO Sunil*/
2857 if ((1<<4) & StaParams.extn_capability[3]) {
2858 isBufSta = 1;
2859 }
2860 }
2861 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2862 "%s: TDLS Peer Parameters.", __func__);
2863 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2864 "uapsd_queues: %0x\n", params->uapsd_queues);
2865 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2866 "max_sp: %0x\n", params->max_sp);
2867 if (params->ht_capa) {
2868 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2869 "ht_capa->cap_info: %0x\n", params->ht_capa->cap_info);
2870 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2871 "ht_capa->ampdu_params_info: %0x\n",
2872 params->ht_capa->ampdu_params_info);
2873 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2874 "ht_capa->extended_capabilities: %0x\n",
2875 params->ht_capa->extended_ht_cap_info);
2876 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2877 "ht_capa->tx_BF_cap_info: %0x\n",
2878 params->ht_capa->tx_BF_cap_info);
2879 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2880 "ht_capa->antenna_selection_info: %0x\n",
2881 params->ht_capa->antenna_selection_info);
2882 }
2883 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2884 "params->capability: %0x\n",params->capability);
2885 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2886 "params->ext_capab_len: %0x\n",params->ext_capab_len);
2887 if (0 != params->ext_capab_len )
2888 {
2889 int i =0;
2890 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2891 "Extended capabilities:");
2892 for (i=0; i < params->ext_capab_len; i++)
2893 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2894 "[%d]: %0x", i, params->ext_capab[i]);
2895 }
2896 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
2897 // params->max_sp, isBufSta);
2898 if (VOS_STATUS_SUCCESS != status) {
2899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2900 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
2901 return -EINVAL;
2902 }
2903 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2904 "ht_capa->cap_info: %0x\n", StaParams.HTCap.capInfo);
2905 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
2906
2907 if (VOS_STATUS_SUCCESS != status) {
2908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2909 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
2910 return -EINVAL;
2911 }
2912 }
2913 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002914#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002915
Jeff Johnsone7245742012-09-05 17:12:55 -07002916 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002917 return status;
2918}
2919
2920/*
2921 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2922 * This function is used to get peer station index in IBSS mode
2923 */
2924static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2925{
2926 u8 idx = 0;
2927 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2928 ENTER();
2929 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2930 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2931 {
2932 if ( (0 !=
2933 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2934 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2935 temp, VOS_MAC_ADDR_SIZE)
2936 )
2937 {
2938 return idx;
2939 }
2940 }
2941 return idx;
2942}
2943
2944
2945/*
2946 * FUNCTION: wlan_hdd_cfg80211_add_key
2947 * This function is used to initialize the key information
2948 */
2949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2950static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2951 struct net_device *ndev,
2952 u8 key_index, bool pairwise,
2953 const u8 *mac_addr,
2954 struct key_params *params
2955 )
2956#else
2957static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2958 struct net_device *ndev,
2959 u8 key_index, const u8 *mac_addr,
2960 struct key_params *params
2961 )
2962#endif
2963{
2964 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2965 tCsrRoamSetKey setKey;
2966 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2967 int status = 0;
2968 v_U32_t roamId= 0xFF;
2969 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2970 hdd_hostapd_state_t *pHostapdState;
2971 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002972 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002973
2974 ENTER();
2975
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002976 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2977 {
2978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2979 "%s:LOGP in Progress. Ignore!!!", __func__);
2980 return -EAGAIN;
2981 }
2982
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2984 __func__,pAdapter->device_mode);
2985
2986 if (CSR_MAX_NUM_KEY <= key_index)
2987 {
2988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2989 key_index);
2990
2991 return -EINVAL;
2992 }
2993
2994 hddLog(VOS_TRACE_LEVEL_INFO,
2995 "%s: called with key index = %d & key length %d",
2996 __func__, key_index, params->key_len);
2997
2998 /*extract key idx, key len and key*/
2999 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3000 setKey.keyId = key_index;
3001 setKey.keyLength = params->key_len;
3002 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3003
3004 switch (params->cipher)
3005 {
3006 case WLAN_CIPHER_SUITE_WEP40:
3007 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3008 break;
3009
3010 case WLAN_CIPHER_SUITE_WEP104:
3011 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3012 break;
3013
3014 case WLAN_CIPHER_SUITE_TKIP:
3015 {
3016 u8 *pKey = &setKey.Key[0];
3017 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3018
3019 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3020
3021 /*Supplicant sends the 32bytes key in this order
3022
3023 |--------------|----------|----------|
3024 | Tk1 |TX-MIC | RX Mic |
3025 |--------------|----------|----------|
3026 <---16bytes---><--8bytes--><--8bytes-->
3027
3028 */
3029 /*Sme expects the 32 bytes key to be in the below order
3030
3031 |--------------|----------|----------|
3032 | Tk1 |RX-MIC | TX Mic |
3033 |--------------|----------|----------|
3034 <---16bytes---><--8bytes--><--8bytes-->
3035 */
3036 /* Copy the Temporal Key 1 (TK1) */
3037 vos_mem_copy(pKey, params->key,16);
3038
3039 /*Copy the rx mic first*/
3040 vos_mem_copy(&pKey[16],&params->key[24],8);
3041
3042 /*Copy the tx mic */
3043 vos_mem_copy(&pKey[24],&params->key[16],8);
3044
3045
3046 break;
3047 }
3048
3049 case WLAN_CIPHER_SUITE_CCMP:
3050 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3051 break;
3052
3053#ifdef FEATURE_WLAN_WAPI
3054 case WLAN_CIPHER_SUITE_SMS4:
3055 {
3056 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3057 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3058 params->key, params->key_len);
3059 return 0;
3060 }
3061#endif
3062#ifdef FEATURE_WLAN_CCX
3063 case WLAN_CIPHER_SUITE_KRK:
3064 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3065 break;
3066#endif
3067 default:
3068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3069 __func__, params->cipher);
3070 return -EOPNOTSUPP;
3071 }
3072
3073 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3074 __func__, setKey.encType);
3075
3076
3077
3078 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003080 )
3081 {
3082
3083
3084 if (
3085#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3086 (!pairwise)
3087#else
3088 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3089#endif
3090 )
3091 {
3092 /* set group key*/
3093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003094 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 __func__, __LINE__);
3096 setKey.keyDirection = eSIR_RX_ONLY;
3097 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3098 }
3099 else
3100 {
3101 /* set pairwise key*/
3102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3103 "%s- %d: setting pairwise key",
3104 __func__, __LINE__);
3105 setKey.keyDirection = eSIR_TX_RX;
3106 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3107 }
3108
3109 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3110 if( pHostapdState->bssState == BSS_START )
3111 {
3112 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3113
3114 if ( status != eHAL_STATUS_SUCCESS )
3115 {
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3117 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3118 __LINE__, status );
3119 }
3120 }
3121
3122 /* Saving WEP keys */
3123 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3124 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3125 {
3126 //Save the wep key in ap context. Issue setkey after the BSS is started.
3127 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3128 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3129 }
3130 else
3131 {
3132 //Save the key in ap context. Issue setkey after the BSS is started.
3133 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3134 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3135 }
3136 }
3137 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003138 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003139 )
3140 {
3141 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3142 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3143
3144 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3145
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003146 pWextState->roamProfile.Keys.defaultIndex = key_index;
3147
3148
Jeff Johnson295189b2012-06-20 16:38:30 -07003149 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3150 params->key, params->key_len);
3151
3152 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3153
3154 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3155 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3156 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3157 )
3158 &&
3159 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3160 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3161 )
3162 )
3163 {
3164 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3165 * interface, copy bssid for pairwise key and group macaddr for
3166 * group key initialization*/
3167
3168 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3169
3170 pWextState->roamProfile.negotiatedUCEncryptionType =
3171 pHddStaCtx->conn_info.ucEncryptionType =
3172 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3173 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3174 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3175
3176
3177 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3178 "%s: Negotiated encryption type %d", __func__,
3179 pWextState->roamProfile.negotiatedUCEncryptionType);
3180
3181 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3182 &pWextState->roamProfile, true);
3183 setKey.keyLength = 0;
3184 setKey.keyDirection = eSIR_TX_RX;
3185
3186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3187 if (pairwise)
3188 {
3189#endif
3190 if (mac_addr)
3191 {
3192 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3193 }
3194 else
3195 {
3196 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3197 * and peerMacAddress in case of IBSS*/
3198 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3199 {
3200 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3201 if (HDD_MAX_NUM_IBSS_STA != staidx)
3202 {
3203 vos_mem_copy(setKey.peerMac,
3204 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3205 WNI_CFG_BSSID_LEN);
3206
3207 }
3208 else
3209 {
3210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3211 __func__);
3212 return -EOPNOTSUPP;
3213 }
3214 }
3215 else
3216 {
3217 vos_mem_copy(setKey.peerMac,
3218 &pHddStaCtx->conn_info.bssId[0],
3219 WNI_CFG_BSSID_LEN);
3220 }
3221 }
3222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3223 }
3224 else
3225 {
3226 /* set group key*/
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3228 "%s- %d: setting Group key",
3229 __func__, __LINE__);
3230 setKey.keyDirection = eSIR_RX_ONLY;
3231 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3232 }
3233#endif
3234 }
3235 else if (
3236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3237 (!pairwise)
3238#else
3239 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3240#endif
3241 )
3242 {
3243 /* set group key*/
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3245 "%s- %d: setting Group key",
3246 __func__, __LINE__);
3247 setKey.keyDirection = eSIR_RX_ONLY;
3248 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3249 }
3250 else
3251 {
3252 /* set pairwise key*/
3253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3254 "%s- %d: setting pairwise key",
3255 __func__, __LINE__);
3256 setKey.keyDirection = eSIR_TX_RX;
3257 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3258 }
3259
3260 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3261 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3262 __func__, setKey.peerMac[0], setKey.peerMac[1],
3263 setKey.peerMac[2], setKey.peerMac[3],
3264 setKey.peerMac[4], setKey.peerMac[5],
3265 setKey.keyDirection);
3266
3267 vos_status = wlan_hdd_check_ula_done(pAdapter);
3268
3269 if ( vos_status != VOS_STATUS_SUCCESS )
3270 {
3271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3272 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3273 __LINE__, vos_status );
3274
3275 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3276
3277 return -EINVAL;
3278
3279 }
3280
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003281#ifdef WLAN_FEATURE_VOWIFI_11R
3282 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3283 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003284 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303285 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003286 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303287 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003288 }
3289#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003290
3291 /* issue set key request to SME*/
3292 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3293 pAdapter->sessionId, &setKey, &roamId );
3294
3295 if ( 0 != status )
3296 {
3297 hddLog(VOS_TRACE_LEVEL_ERROR,
3298 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3299 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3300 return -EINVAL;
3301 }
3302
3303
3304 /* in case of IBSS as there was no information available about WEP keys during
3305 * IBSS join, group key intialized with NULL key, so re-initialize group key
3306 * with correct value*/
3307 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3308 !( ( IW_AUTH_KEY_MGMT_802_1X
3309 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3310 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3311 )
3312 &&
3313 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3314 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3315 )
3316 )
3317 {
3318 setKey.keyDirection = eSIR_RX_ONLY;
3319 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3320
3321 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3322 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3323 __func__, setKey.peerMac[0], setKey.peerMac[1],
3324 setKey.peerMac[2], setKey.peerMac[3],
3325 setKey.peerMac[4], setKey.peerMac[5],
3326 setKey.keyDirection);
3327
3328 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3329 pAdapter->sessionId, &setKey, &roamId );
3330
3331 if ( 0 != status )
3332 {
3333 hddLog(VOS_TRACE_LEVEL_ERROR,
3334 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3335 __func__, status);
3336 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3337 return -EINVAL;
3338 }
3339 }
3340 }
3341
3342 return 0;
3343}
3344
3345/*
3346 * FUNCTION: wlan_hdd_cfg80211_get_key
3347 * This function is used to get the key information
3348 */
3349#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3350static int wlan_hdd_cfg80211_get_key(
3351 struct wiphy *wiphy,
3352 struct net_device *ndev,
3353 u8 key_index, bool pairwise,
3354 const u8 *mac_addr, void *cookie,
3355 void (*callback)(void *cookie, struct key_params*)
3356 )
3357#else
3358static int wlan_hdd_cfg80211_get_key(
3359 struct wiphy *wiphy,
3360 struct net_device *ndev,
3361 u8 key_index, const u8 *mac_addr, void *cookie,
3362 void (*callback)(void *cookie, struct key_params*)
3363 )
3364#endif
3365{
3366 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3367 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3368 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3369 struct key_params params;
3370
3371 ENTER();
3372
3373 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3374 __func__,pAdapter->device_mode);
3375
3376 memset(&params, 0, sizeof(params));
3377
3378 if (CSR_MAX_NUM_KEY <= key_index)
3379 {
3380 return -EINVAL;
3381 }
3382
3383 switch(pRoamProfile->EncryptionType.encryptionType[0])
3384 {
3385 case eCSR_ENCRYPT_TYPE_NONE:
3386 params.cipher = IW_AUTH_CIPHER_NONE;
3387 break;
3388
3389 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3390 case eCSR_ENCRYPT_TYPE_WEP40:
3391 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3392 break;
3393
3394 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3395 case eCSR_ENCRYPT_TYPE_WEP104:
3396 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3397 break;
3398
3399 case eCSR_ENCRYPT_TYPE_TKIP:
3400 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3401 break;
3402
3403 case eCSR_ENCRYPT_TYPE_AES:
3404 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3405 break;
3406
3407 default:
3408 params.cipher = IW_AUTH_CIPHER_NONE;
3409 break;
3410 }
3411
3412 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3413 params.seq_len = 0;
3414 params.seq = NULL;
3415 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3416 callback(cookie, &params);
3417 return 0;
3418}
3419
3420/*
3421 * FUNCTION: wlan_hdd_cfg80211_del_key
3422 * This function is used to delete the key information
3423 */
3424#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3425static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3426 struct net_device *ndev,
3427 u8 key_index,
3428 bool pairwise,
3429 const u8 *mac_addr
3430 )
3431#else
3432static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3433 struct net_device *ndev,
3434 u8 key_index,
3435 const u8 *mac_addr
3436 )
3437#endif
3438{
3439 int status = 0;
3440
3441 //This code needs to be revisited. There is sme_removeKey API, we should
3442 //plan to use that. After the change to use correct index in setkey,
3443 //it is observed that this is invalidating peer
3444 //key index whenever re-key is done. This is affecting data link.
3445 //It should be ok to ignore del_key.
3446#if 0
3447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3448 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3449 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3450 tCsrRoamSetKey setKey;
3451 v_U32_t roamId= 0xFF;
3452
3453 ENTER();
3454
3455 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3456 __func__,pAdapter->device_mode);
3457
3458 if (CSR_MAX_NUM_KEY <= key_index)
3459 {
3460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3461 key_index);
3462
3463 return -EINVAL;
3464 }
3465
3466 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3467 setKey.keyId = key_index;
3468
3469 if (mac_addr)
3470 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3471 else
3472 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3473
3474 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3475
3476 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003477 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003478 )
3479 {
3480
3481 hdd_hostapd_state_t *pHostapdState =
3482 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3483 if( pHostapdState->bssState == BSS_START)
3484 {
3485 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3486
3487 if ( status != eHAL_STATUS_SUCCESS )
3488 {
3489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3491 __LINE__, status );
3492 }
3493 }
3494 }
3495 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003496 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003497 )
3498 {
3499 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3500
3501 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3502
3503 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3504 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3505 __func__, setKey.peerMac[0], setKey.peerMac[1],
3506 setKey.peerMac[2], setKey.peerMac[3],
3507 setKey.peerMac[4], setKey.peerMac[5]);
3508 if(pAdapter->sessionCtx.station.conn_info.connState ==
3509 eConnectionState_Associated)
3510 {
3511 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3512 pAdapter->sessionId, &setKey, &roamId );
3513
3514 if ( 0 != status )
3515 {
3516 hddLog(VOS_TRACE_LEVEL_ERROR,
3517 "%s: sme_RoamSetKey failure, returned %d",
3518 __func__, status);
3519 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3520 return -EINVAL;
3521 }
3522 }
3523 }
3524#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003525 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 return status;
3527}
3528
3529/*
3530 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3531 * This function is used to set the default tx key index
3532 */
3533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3534static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3535 struct net_device *ndev,
3536 u8 key_index,
3537 bool unicast, bool multicast)
3538#else
3539static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3540 struct net_device *ndev,
3541 u8 key_index)
3542#endif
3543{
3544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3545 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3546 int status = 0;
3547 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3548
3549 ENTER();
3550
3551 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3552 __func__,pAdapter->device_mode, key_index);
3553
3554 if (CSR_MAX_NUM_KEY <= key_index)
3555 {
3556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3557 key_index);
3558
3559 return -EINVAL;
3560 }
3561
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003562 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3563 {
3564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3565 "%s:LOGP in Progress. Ignore!!!", __func__);
3566 return -EAGAIN;
3567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003568
3569 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003570 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003571 )
3572 {
3573 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3574 (eCSR_ENCRYPT_TYPE_TKIP !=
3575 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3576 (eCSR_ENCRYPT_TYPE_AES !=
3577 pWextState->roamProfile.EncryptionType.encryptionType[0])
3578 )
3579 {
3580 /* if default key index is not same as previous one,
3581 * then update the default key index */
3582
3583 tCsrRoamSetKey setKey;
3584 v_U32_t roamId= 0xFF;
3585 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3586
3587 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3588 __func__, key_index);
3589
3590 Keys->defaultIndex = (u8)key_index;
3591 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3592 setKey.keyId = key_index;
3593 setKey.keyLength = Keys->KeyLength[key_index];
3594
3595 vos_mem_copy(&setKey.Key[0],
3596 &Keys->KeyMaterial[key_index][0],
3597 Keys->KeyLength[key_index]);
3598
3599 setKey.keyDirection = eSIR_TX_ONLY;
3600
3601 vos_mem_copy(setKey.peerMac,
3602 &pHddStaCtx->conn_info.bssId[0],
3603 WNI_CFG_BSSID_LEN);
3604
3605 setKey.encType =
3606 pWextState->roamProfile.EncryptionType.encryptionType[0];
3607
3608 /* issue set key request */
3609 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3610 pAdapter->sessionId, &setKey, &roamId );
3611
3612 if ( 0 != status )
3613 {
3614 hddLog(VOS_TRACE_LEVEL_ERROR,
3615 "%s: sme_RoamSetKey failed, returned %d", __func__,
3616 status);
3617 return -EINVAL;
3618 }
3619 }
3620 }
3621
3622 /* In SoftAp mode setting key direction for default mode */
3623 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3624 {
3625 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3626 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3627 (eCSR_ENCRYPT_TYPE_AES !=
3628 pWextState->roamProfile.EncryptionType.encryptionType[0])
3629 )
3630 {
3631 /* Saving key direction for default key index to TX default */
3632 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3633 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3634 }
3635 }
3636
3637 return status;
3638}
3639
Jeff Johnson295189b2012-06-20 16:38:30 -07003640/*
3641 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3642 * This function is used to inform the BSS details to nl80211 interface.
3643 */
3644static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3645 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3646{
3647 struct net_device *dev = pAdapter->dev;
3648 struct wireless_dev *wdev = dev->ieee80211_ptr;
3649 struct wiphy *wiphy = wdev->wiphy;
3650 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3651 int chan_no;
3652 int ie_length;
3653 const char *ie;
3654 unsigned int freq;
3655 struct ieee80211_channel *chan;
3656 int rssi = 0;
3657 struct cfg80211_bss *bss = NULL;
3658
3659 ENTER();
3660
3661 if( NULL == pBssDesc )
3662 {
3663 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3664 return bss;
3665 }
3666
3667 chan_no = pBssDesc->channelId;
3668 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3669 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3670
3671 if( NULL == ie )
3672 {
3673 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3674 return bss;
3675 }
3676
3677#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3678 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3679 {
3680 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3681 }
3682 else
3683 {
3684 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3685 }
3686#else
3687 freq = ieee80211_channel_to_frequency(chan_no);
3688#endif
3689
3690 chan = __ieee80211_get_channel(wiphy, freq);
3691
3692 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3693 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3694 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3695 if (bss == NULL)
3696 {
3697 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3698
3699 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3700 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3701 pBssDesc->capabilityInfo,
3702 pBssDesc->beaconInterval, ie, ie_length,
3703 rssi, GFP_KERNEL ));
3704}
3705 else
3706 {
3707 return bss;
3708 }
3709}
3710
3711
3712
3713/*
3714 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3715 * This function is used to inform the BSS details to nl80211 interface.
3716 */
3717struct cfg80211_bss*
3718wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3719 tSirBssDescription *bss_desc
3720 )
3721{
3722 /*
3723 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3724 already exists in bss data base of cfg80211 for that particular BSS ID.
3725 Using cfg80211_inform_bss_frame to update the bss entry instead of
3726 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3727 now there is no possibility to get the mgmt(probe response) frame from PE,
3728 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3729 cfg80211_inform_bss_frame.
3730 */
3731 struct net_device *dev = pAdapter->dev;
3732 struct wireless_dev *wdev = dev->ieee80211_ptr;
3733 struct wiphy *wiphy = wdev->wiphy;
3734 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003735#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3736 qcom_ie_age *qie_age = NULL;
3737 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3738#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003739 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003740#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 const char *ie =
3742 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3743 unsigned int freq;
3744 struct ieee80211_channel *chan;
3745 struct ieee80211_mgmt *mgmt =
3746 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3747 struct cfg80211_bss *bss_status = NULL;
3748 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3749 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003750#ifdef WLAN_OPEN_SOURCE
3751 struct timespec ts;
3752#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003753
3754 ENTER();
3755
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003756 if (!mgmt)
3757 return NULL;
3758
Jeff Johnson295189b2012-06-20 16:38:30 -07003759 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003760
3761#ifdef WLAN_OPEN_SOURCE
3762 /* Android does not want the timestamp from the frame.
3763 Instead it wants a monotonic increasing value */
3764 get_monotonic_boottime(&ts);
3765 mgmt->u.probe_resp.timestamp =
3766 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3767#else
3768 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003769 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3770 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003771
3772#endif
3773
Jeff Johnson295189b2012-06-20 16:38:30 -07003774 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3775 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003776
3777#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3778 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3779 /* Assuming this is the last IE, copy at the end */
3780 ie_length -=sizeof(qcom_ie_age);
3781 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3782 qie_age->element_id = QCOM_VENDOR_IE_ID;
3783 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3784 qie_age->oui_1 = QCOM_OUI1;
3785 qie_age->oui_2 = QCOM_OUI2;
3786 qie_age->oui_3 = QCOM_OUI3;
3787 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3788 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3789#endif
3790
Jeff Johnson295189b2012-06-20 16:38:30 -07003791 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3792
3793 mgmt->frame_control |=
3794 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3795
3796#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3797 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3798 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3799 {
3800 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3801 }
3802 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3803 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3804
3805 {
3806 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3807 }
3808 else
3809 {
3810 kfree(mgmt);
3811 return NULL;
3812 }
3813#else
3814 freq = ieee80211_channel_to_frequency(chan_no);
3815#endif
3816 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003817 /*when the band is changed on the fly using the GUI, three things are done
3818 * 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)
3819 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3820 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3821 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3822 * and discards the channels correponding to previous band and calls back with zero bss results.
3823 * 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
3824 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3825 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3826 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3827 * So drop the bss and continue to next bss.
3828 */
3829 if(chan == NULL)
3830 {
3831 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3832 return NULL;
3833 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003834 /*To keep the rssi icon of the connected AP in the scan window
3835 *and the rssi icon of the wireless networks in sync
3836 * */
3837 if (( eConnectionState_Associated ==
3838 pAdapter->sessionCtx.station.conn_info.connState ) &&
3839 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3840 pAdapter->sessionCtx.station.conn_info.bssId,
3841 WNI_CFG_BSSID_LEN)))
3842 {
3843 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3844 rssi = (pAdapter->rssi * 100);
3845 }
3846 else
3847 {
3848 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3849 }
3850
3851 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3852 frame_len, rssi, GFP_KERNEL);
3853 kfree(mgmt);
3854 return bss_status;
3855}
3856
3857/*
3858 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3859 * This function is used to update the BSS data base of CFG8011
3860 */
3861struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3862 tCsrRoamInfo *pRoamInfo
3863 )
3864{
3865 tCsrRoamConnectedProfile roamProfile;
3866 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3867 struct cfg80211_bss *bss = NULL;
3868
3869 ENTER();
3870
3871 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3872 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3873
3874 if (NULL != roamProfile.pBssDesc)
3875 {
3876 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3877 &roamProfile);
3878
3879 if (NULL == bss)
3880 {
3881 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3882 __func__);
3883 }
3884
3885 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3886 }
3887 else
3888 {
3889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3890 __func__);
3891 }
3892 return bss;
3893}
3894
3895/*
3896 * FUNCTION: wlan_hdd_cfg80211_update_bss
3897 */
3898static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3899 hdd_adapter_t *pAdapter
3900 )
3901{
3902 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3903 tCsrScanResultInfo *pScanResult;
3904 eHalStatus status = 0;
3905 tScanResultHandle pResult;
3906 struct cfg80211_bss *bss_status = NULL;
3907
3908 ENTER();
3909
3910 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3911 {
3912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3913 return -EAGAIN;
3914 }
3915
3916 /*
3917 * start getting scan results and populate cgf80211 BSS database
3918 */
3919 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3920
3921 /* no scan results */
3922 if (NULL == pResult)
3923 {
3924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3925 return status;
3926 }
3927
3928 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3929
3930 while (pScanResult)
3931 {
3932 /*
3933 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3934 * entry already exists in bss data base of cfg80211 for that
3935 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3936 * bss entry instead of cfg80211_inform_bss, But this call expects
3937 * mgmt packet as input. As of now there is no possibility to get
3938 * the mgmt(probe response) frame from PE, converting bss_desc to
3939 * ieee80211_mgmt(probe response) and passing to c
3940 * fg80211_inform_bss_frame.
3941 * */
3942
3943 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3944 &pScanResult->BssDescriptor);
3945
3946
3947 if (NULL == bss_status)
3948 {
3949 hddLog(VOS_TRACE_LEVEL_INFO,
3950 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3951 }
3952 else
3953 {
3954 cfg80211_put_bss(bss_status);
3955 }
3956
3957 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3958 }
3959
3960 sme_ScanResultPurge(hHal, pResult);
3961
3962 return 0;
3963}
3964
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003965void
3966hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3967{
3968 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003969 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3970 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3971 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003972} /****** end hddPrintMacAddr() ******/
3973
3974void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003975hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003976{
3977 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003978 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3979 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3980 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3981 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003982} /****** end hddPrintPmkId() ******/
3983
3984//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3985//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3986
3987//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3988//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3989
3990#define dump_bssid(bssid) \
3991 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003992 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3993 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3994 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003995 }
3996
3997#define dump_pmkid(pMac, pmkid) \
3998 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003999 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4000 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4001 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004002 }
4003
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004004#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004005/*
4006 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4007 * This function is used to notify the supplicant of a new PMKSA candidate.
4008 */
4009int wlan_hdd_cfg80211_pmksa_candidate_notify(
4010 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
4011 int index, bool preauth )
4012{
Jeff Johnsone7245742012-09-05 17:12:55 -07004013#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004014 struct net_device *dev = pAdapter->dev;
4015
4016 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004017 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004018
4019 if( NULL == pRoamInfo )
4020 {
4021 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4022 return -EINVAL;
4023 }
4024
4025 dump_bssid(pRoamInfo->bssid);
4026 cfg80211_pmksa_candidate_notify(dev, index,
4027 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07004028#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004029 return 0;
4030}
4031#endif //FEATURE_WLAN_LFR
4032
Jeff Johnson295189b2012-06-20 16:38:30 -07004033/*
4034 * FUNCTION: hdd_cfg80211_scan_done_callback
4035 * scanning callback function, called after finishing scan
4036 *
4037 */
4038static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
4039 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4040{
4041 struct net_device *dev = (struct net_device *) pContext;
4042 //struct wireless_dev *wdev = dev->ieee80211_ptr;
4043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004044 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4045 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004046 struct cfg80211_scan_request *req = NULL;
4047 int ret = 0;
4048
4049 ENTER();
4050
4051 hddLog(VOS_TRACE_LEVEL_INFO,
4052 "%s called with halHandle = %p, pContext = %p,"
4053 "scanID = %d, returned status = %d\n",
4054 __func__, halHandle, pContext, (int) scanId, (int) status);
4055
4056 //Block on scan req completion variable. Can't wait forever though.
4057 ret = wait_for_completion_interruptible_timeout(
4058 &pScanInfo->scan_req_completion_event,
4059 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4060 if (!ret)
4061 {
4062 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004063 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004064 }
4065
4066 if(pScanInfo->mScanPending != VOS_TRUE)
4067 {
4068 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004069 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 }
4071
4072 /* Check the scanId */
4073 if (pScanInfo->scanId != scanId)
4074 {
4075 hddLog(VOS_TRACE_LEVEL_INFO,
4076 "%s called with mismatched scanId pScanInfo->scanId = %d "
4077 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
4078 (int) scanId);
4079 }
4080
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
4082 pAdapter);
4083
4084 if (0 > ret)
4085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
4086
4087
4088 /* If any client wait scan result through WEXT
4089 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004090 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004091 {
4092 /* The other scan request waiting for current scan finish
4093 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004094 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004095 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004096 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004097 }
4098 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004099 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004100 {
4101 struct net_device *dev = pAdapter->dev;
4102 union iwreq_data wrqu;
4103 int we_event;
4104 char *msg;
4105
4106 memset(&wrqu, '\0', sizeof(wrqu));
4107 we_event = SIOCGIWSCAN;
4108 msg = NULL;
4109 wireless_send_event(dev, we_event, &wrqu, msg);
4110 }
4111 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004112 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004113
4114 /* Get the Scan Req */
4115 req = pAdapter->request;
4116
4117 if (!req)
4118 {
4119 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004120 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004121 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004122 }
4123
4124 /*
4125 * setting up 0, just in case.
4126 */
4127 req->n_ssids = 0;
4128 req->n_channels = 0;
4129 req->ie = 0;
4130
Jeff Johnson295189b2012-06-20 16:38:30 -07004131 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004132 /* Scan is no longer pending */
4133 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004134
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004135 /*
4136 * cfg80211_scan_done informing NL80211 about completion
4137 * of scanning
4138 */
4139 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004140 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004141
Jeff Johnsone7245742012-09-05 17:12:55 -07004142allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004143 /* release the wake lock at the end of the scan*/
4144 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004145
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004146 /* Acquire wakelock to handle the case where APP's tries to suspend
4147 * immediatly after the driver gets connect request(i.e after scan)
4148 * from supplicant, this result in app's is suspending and not able
4149 * to process the connect request to AP */
4150 hdd_allow_suspend_timeout(100);
4151
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 EXIT();
4153 return 0;
4154}
4155
4156/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004157 * FUNCTION: hdd_isScanAllowed
4158 * Go through each adapter and check if scan allowed
4159 *
4160 */
4161v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4162{
4163 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4164 hdd_station_ctx_t *pHddStaCtx = NULL;
4165 hdd_adapter_t *pAdapter = NULL;
4166 VOS_STATUS status = 0;
4167 v_U8_t staId = 0;
4168 v_U8_t *staMac = NULL;
4169
4170 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4171
4172 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4173 {
4174 pAdapter = pAdapterNode->pAdapter;
4175
4176 if( pAdapter )
4177 {
4178 hddLog(VOS_TRACE_LEVEL_INFO,
4179 "%s: Adapter with device mode %d exists",
4180 __func__, pAdapter->device_mode);
4181 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4182 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4183 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4184 {
4185 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4186 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4187 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4188 {
4189 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4190 hddLog(VOS_TRACE_LEVEL_ERROR,
4191 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4192 "middle of WPS/EAPOL exchange.", __func__,
4193 staMac[0], staMac[1], staMac[2],
4194 staMac[3], staMac[4], staMac[5]);
4195 return VOS_FALSE;
4196 }
4197 }
4198 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4199 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4200 {
4201 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4202 {
4203 if ((pAdapter->aStaInfo[staId].isUsed) &&
4204 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4205 {
4206 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4207
4208 hddLog(VOS_TRACE_LEVEL_ERROR,
4209 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4210 "middle of WPS/EAPOL exchange.", __func__,
4211 staMac[0], staMac[1], staMac[2],
4212 staMac[3], staMac[4], staMac[5]);
4213 return VOS_FALSE;
4214 }
4215 }
4216 }
4217 }
4218 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4219 pAdapterNode = pNext;
4220 }
4221 hddLog(VOS_TRACE_LEVEL_INFO,
4222 "%s: Scan allowed", __func__);
4223 return VOS_TRUE;
4224}
4225
4226/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 * FUNCTION: wlan_hdd_cfg80211_scan
4228 * this scan respond to scan trigger and update cfg80211 scan database
4229 * later, scan dump command can be used to recieve scan results
4230 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004231int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4232#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4233 struct net_device *dev,
4234#endif
4235 struct cfg80211_scan_request *request)
4236{
4237#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4238 struct net_device *dev = request->wdev->netdev;
4239#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4241 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4242 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4243 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4244 tCsrScanRequest scanRequest;
4245 tANI_U8 *channelList = NULL, i;
4246 v_U32_t scanId = 0;
4247 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004248 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004249 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004250
4251 ENTER();
4252
4253 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4254 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004255
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004256 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004257 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004258 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004259 {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004261 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4262 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004263 return -EBUSY;
4264 }
4265
Jeff Johnson295189b2012-06-20 16:38:30 -07004266#ifdef WLAN_BTAMP_FEATURE
4267 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004268 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004269 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004270 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 "%s: No scanning when AMP is on", __func__);
4272 return -EOPNOTSUPP;
4273 }
4274#endif
4275 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004276 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004277 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004278 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004279 "%s: Not scanning on device_mode = %d",
4280 __func__, pAdapter->device_mode);
4281 return -EOPNOTSUPP;
4282 }
4283
4284 if (TRUE == pScanInfo->mScanPending)
4285 {
4286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004287 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004288 }
4289
4290 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4291 {
4292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4293 "%s:LOGP in Progress. Ignore!!!", __func__);
4294 return -EAGAIN;
4295 }
4296
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004297 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4298 {
4299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4300 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4301 return -EAGAIN;
4302 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004303 //Don't Allow Scan and return busy if Remain On
4304 //Channel and action frame is pending
4305 //Otherwise Cancel Remain On Channel and allow Scan
4306 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004307 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004308 {
4309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4310 return -EBUSY;
4311 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004312#ifdef FEATURE_WLAN_TDLS
4313 if (wlan_hdd_tdlsConnectedPeers(pAdapter))
4314 {
4315 tANI_U8 staIdx;
4316
4317 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
4318 {
4319 if (pHddCtx->tdlsConnInfo[staIdx].staId)
4320 {
4321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4322 ("scan: indicate TDLS teadown (staId %d)"), pHddCtx->tdlsConnInfo[staIdx].staId) ;
4323
4324#ifdef CONFIG_TDLS_IMPLICIT
4325 cfg80211_tdls_oper_request(pAdapter->dev,
4326 pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes,
4327 NL80211_TDLS_TEARDOWN,
4328 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
4329 GFP_KERNEL);
4330#endif
4331 }
4332 }
4333 return -EBUSY;
4334 }
4335#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004336
Jeff Johnson295189b2012-06-20 16:38:30 -07004337 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4338 {
4339 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004340 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004341 return -EAGAIN;
4342 }
4343 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4344 {
4345 hddLog(VOS_TRACE_LEVEL_WARN,
4346 "%s: MAX TM Level Scan not allowed", __func__);
4347 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4348 return -EBUSY;
4349 }
4350 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4351
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004352 /* Check if scan is allowed at this point of time.
4353 */
4354 if (!hdd_isScanAllowed(pHddCtx))
4355 {
4356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4357 return -EBUSY;
4358 }
4359
Jeff Johnson295189b2012-06-20 16:38:30 -07004360 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4361
4362 if (NULL != request)
4363 {
4364 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4365 (int)request->n_ssids);
4366
4367 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4368 * Becasue of this, driver is assuming that this is not wildcard scan and so
4369 * is not aging out the scan results.
4370 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004371 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 {
4373 request->n_ssids = 0;
4374 }
4375
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004376 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004377 {
4378 tCsrSSIDInfo *SsidInfo;
4379 int j;
4380 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4381 /* Allocate num_ssid tCsrSSIDInfo structure */
4382 SsidInfo = scanRequest.SSIDs.SSIDList =
4383 ( tCsrSSIDInfo *)vos_mem_malloc(
4384 request->n_ssids*sizeof(tCsrSSIDInfo));
4385
4386 if(NULL == scanRequest.SSIDs.SSIDList)
4387 {
4388 hddLog(VOS_TRACE_LEVEL_ERROR,
4389 "memory alloc failed SSIDInfo buffer");
4390 return -ENOMEM;
4391 }
4392
4393 /* copy all the ssid's and their length */
4394 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4395 {
4396 /* get the ssid length */
4397 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4398 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4399 SsidInfo->SSID.length);
4400 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4401 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4402 j, SsidInfo->SSID.ssId);
4403 }
4404 /* set the scan type to active */
4405 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4406 }
4407 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4408 {
4409 /* set the scan type to active */
4410 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4411 }
4412 else
4413 {
4414 /*Set the scan type to default type, in this case it is ACTIVE*/
4415 scanRequest.scanType = pScanInfo->scan_mode;
4416 }
4417 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4418 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4419 }
4420 else
4421 {
4422 /* set the scan type to active */
4423 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4424 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4425
4426 /* set min and max channel time to zero */
4427 scanRequest.minChnTime = 0;
4428 scanRequest.maxChnTime = 0;
4429 }
4430
4431 /* set BSSType to default type */
4432 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4433
4434 /*TODO: scan the requested channels only*/
4435
4436 /*Right now scanning all the channels */
4437 if( request )
4438 {
4439 if( request->n_channels )
4440 {
4441 channelList = vos_mem_malloc( request->n_channels );
4442 if( NULL == channelList )
4443 {
4444 status = -ENOMEM;
4445 goto free_mem;
4446 }
4447
4448 for( i = 0 ; i < request->n_channels ; i++ )
4449 channelList[i] = request->channels[i]->hw_value;
4450 }
4451
4452 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4453 scanRequest.ChannelInfo.ChannelList = channelList;
4454
4455 /* set requestType to full scan */
4456 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004457
4458 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4459 * search (Flush on both full scan and social scan but not on single
4460 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4461 */
4462
4463 /* Supplicant does single channel scan after 8-way handshake
4464 * and in that case driver shoudnt flush scan results. If
4465 * driver flushes the scan results here and unfortunately if
4466 * the AP doesnt respond to our probe req then association
4467 * fails which is not desired
4468 */
4469
4470 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4471 {
4472 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4473 pAdapter->sessionId );
4474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004475
4476 if( request->ie_len )
4477 {
4478 /* save this for future association (join requires this) */
4479 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4480 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4481 pScanInfo->scanAddIE.length = request->ie_len;
4482
4483 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004484 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4485 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004486 )
4487 {
4488 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4489 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4490 }
4491
4492 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4493 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4494
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4496 request->ie_len);
4497 if (pP2pIe != NULL)
4498 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004499#ifdef WLAN_FEATURE_P2P_DEBUG
4500 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4501 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4502 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4503 {
4504 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4505 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4506 "Go nego completed to Connection is started");
4507 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4508 "for 8way Handshake");
4509 }
4510 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4511 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4512 {
4513 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4514 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4515 "Disconnected state to Connection is started");
4516 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4517 "for 4way Handshake");
4518 }
4519#endif
4520
Jeff Johnsone7245742012-09-05 17:12:55 -07004521 /* no_cck will be set during p2p find to disable 11b rates */
4522 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004523 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 hddLog(VOS_TRACE_LEVEL_INFO,
4525 "%s: This is a P2P Search", __func__);
4526 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004527
Jeff Johnsone7245742012-09-05 17:12:55 -07004528 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4529 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004530 /* set requestType to P2P Discovery */
4531 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004532 }
4533
4534 /*
4535 Skip Dfs Channel in case of P2P Search
4536 if it is set in ini file
4537 */
4538 if(cfg_param->skipDfsChnlInP2pSearch)
4539 {
4540 scanRequest.skipDfsChnlInP2pSearch = 1;
4541 }
4542 else
4543 {
4544 scanRequest.skipDfsChnlInP2pSearch = 0;
4545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004546
Jeff Johnson295189b2012-06-20 16:38:30 -07004547 }
4548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 }
4550 }
4551
4552 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4553
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004554 /* acquire the wakelock to avoid the apps suspend during the scan. To
4555 * address the following issues.
4556 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4557 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4558 * for long time, this result in apps running at full power for long time.
4559 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4560 * be stuck in full power because of resume BMPS
4561 */
4562 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004563
4564 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004565 pAdapter->sessionId, &scanRequest, &scanId,
4566 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004567
Jeff Johnson295189b2012-06-20 16:38:30 -07004568 if (eHAL_STATUS_SUCCESS != status)
4569 {
4570 hddLog(VOS_TRACE_LEVEL_ERROR,
4571 "%s: sme_ScanRequest returned error %d", __func__, status);
4572 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004573 if(eHAL_STATUS_RESOURCES == status)
4574 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004575 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 -07004576 status = -EBUSY;
4577 } else {
4578 status = -EIO;
4579 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004580 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004581 goto free_mem;
4582 }
4583
4584 pScanInfo->mScanPending = TRUE;
4585 pAdapter->request = request;
4586 pScanInfo->scanId = scanId;
4587
4588 complete(&pScanInfo->scan_req_completion_event);
4589
4590free_mem:
4591 if( scanRequest.SSIDs.SSIDList )
4592 {
4593 vos_mem_free(scanRequest.SSIDs.SSIDList);
4594 }
4595
4596 if( channelList )
4597 vos_mem_free( channelList );
4598
4599 EXIT();
4600
4601 return status;
4602}
4603
4604/*
4605 * FUNCTION: wlan_hdd_cfg80211_connect_start
4606 * This function is used to start the association process
4607 */
4608int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004609 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004610{
4611 int status = 0;
4612 hdd_wext_state_t *pWextState;
4613 v_U32_t roamId;
4614 tCsrRoamProfile *pRoamProfile;
4615 eMib_dot11DesiredBssType connectedBssType;
4616 eCsrAuthType RSNAuthType;
4617
4618 ENTER();
4619
4620 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4621
4622 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4625 return -EINVAL;
4626 }
4627
4628 pRoamProfile = &pWextState->roamProfile;
4629
4630 if (pRoamProfile)
4631 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004632 int ret = 0;
4633 hdd_station_ctx_t *pHddStaCtx;
4634 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4635 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4636
4637 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4638 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4639 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004640 {
4641 /* Issue disconnect to CSR */
4642 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4643 if( eHAL_STATUS_SUCCESS ==
4644 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4645 pAdapter->sessionId,
4646 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4647 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004648 ret = wait_for_completion_interruptible_timeout(
4649 &pAdapter->disconnect_comp_var,
4650 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4651 if (0 == ret)
4652 {
4653 VOS_ASSERT(0);
4654 }
4655 }
4656 }
4657 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4658 {
4659 ret = wait_for_completion_interruptible_timeout(
4660 &pAdapter->disconnect_comp_var,
4661 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4662 if (0 == ret)
4663 {
4664 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004665 }
4666 }
4667
4668 if (HDD_WMM_USER_MODE_NO_QOS ==
4669 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4670 {
4671 /*QoS not enabled in cfg file*/
4672 pRoamProfile->uapsd_mask = 0;
4673 }
4674 else
4675 {
4676 /*QoS enabled, update uapsd mask from cfg file*/
4677 pRoamProfile->uapsd_mask =
4678 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4679 }
4680
4681 pRoamProfile->SSIDs.numOfSSIDs = 1;
4682 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4683 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4684 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4685 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4686 ssid, ssid_len);
4687
4688 if (bssid)
4689 {
4690 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4691 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4692 WNI_CFG_BSSID_LEN);
4693 /* Save BSSID in seperate variable as well, as RoamProfile
4694 BSSID is getting zeroed out in the association process. And in
4695 case of join failure we should send valid BSSID to supplicant
4696 */
4697 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4698 WNI_CFG_BSSID_LEN);
4699 }
4700
4701 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4702 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4703 {
4704 /*set gen ie*/
4705 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4706 /*set auth*/
4707 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4708 }
4709 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4710 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4711 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4712 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4713 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4714 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4715 )
4716 {
4717 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4718 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4719 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4720 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4721 eCSR_AUTH_TYPE_AUTOSWITCH;
4722 pWextState->roamProfile.AuthType.authType[0] =
4723 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4724 }
4725#ifdef FEATURE_WLAN_WAPI
4726 if (pAdapter->wapi_info.nWapiMode)
4727 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004728 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004729 switch (pAdapter->wapi_info.wapiAuthMode)
4730 {
4731 case WAPI_AUTH_MODE_PSK:
4732 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004733 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004734 pAdapter->wapi_info.wapiAuthMode);
4735 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4736 break;
4737 }
4738 case WAPI_AUTH_MODE_CERT:
4739 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004740 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004741 pAdapter->wapi_info.wapiAuthMode);
4742 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4743 break;
4744 }
4745 } // End of switch
4746 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4747 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4748 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004749 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004750 pRoamProfile->AuthType.numEntries = 1;
4751 pRoamProfile->EncryptionType.numEntries = 1;
4752 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4753 pRoamProfile->mcEncryptionType.numEntries = 1;
4754 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4755 }
4756 }
4757#endif /* FEATURE_WLAN_WAPI */
4758 pRoamProfile->csrPersona = pAdapter->device_mode;
4759
Jeff Johnson32d95a32012-09-10 13:15:23 -07004760 if( operatingChannel )
4761 {
4762 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4763 pRoamProfile->ChannelInfo.numOfChannels = 1;
4764 }
4765
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004766 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4767 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4768 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4769 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004770 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4771 */
4772 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4773 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4774 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004775
Jeff Johnson295189b2012-06-20 16:38:30 -07004776 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4777 pAdapter->sessionId, pRoamProfile, &roamId);
4778
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004779 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304780 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4781
4782 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4784 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4785 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304786 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004787 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304788 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004789
4790 pRoamProfile->ChannelInfo.ChannelList = NULL;
4791 pRoamProfile->ChannelInfo.numOfChannels = 0;
4792
Jeff Johnson295189b2012-06-20 16:38:30 -07004793 }
4794 else
4795 {
4796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4797 return -EINVAL;
4798 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004799 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 return status;
4801}
4802
4803/*
4804 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4805 * This function is used to set the authentication type (OPEN/SHARED).
4806 *
4807 */
4808static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4809 enum nl80211_auth_type auth_type)
4810{
4811 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4812 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4813
4814 ENTER();
4815
4816 /*set authentication type*/
4817 switch (auth_type)
4818 {
4819 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4820 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004821#ifdef WLAN_FEATURE_VOWIFI_11R
4822 case NL80211_AUTHTYPE_FT:
4823#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 hddLog(VOS_TRACE_LEVEL_INFO,
4825 "%s: set authentication type to OPEN", __func__);
4826 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4827 break;
4828
4829 case NL80211_AUTHTYPE_SHARED_KEY:
4830 hddLog(VOS_TRACE_LEVEL_INFO,
4831 "%s: set authentication type to SHARED", __func__);
4832 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4833 break;
4834#ifdef FEATURE_WLAN_CCX
4835 case NL80211_AUTHTYPE_NETWORK_EAP:
4836 hddLog(VOS_TRACE_LEVEL_INFO,
4837 "%s: set authentication type to CCKM WPA", __func__);
4838 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4839 break;
4840#endif
4841
4842
4843 default:
4844 hddLog(VOS_TRACE_LEVEL_ERROR,
4845 "%s: Unsupported authentication type %d", __func__,
4846 auth_type);
4847 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4848 return -EINVAL;
4849 }
4850
4851 pWextState->roamProfile.AuthType.authType[0] =
4852 pHddStaCtx->conn_info.authType;
4853 return 0;
4854}
4855
4856/*
4857 * FUNCTION: wlan_hdd_set_akm_suite
4858 * This function is used to set the key mgmt type(PSK/8021x).
4859 *
4860 */
4861static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4862 u32 key_mgmt
4863 )
4864{
4865 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4866 ENTER();
4867
4868 /*set key mgmt type*/
4869 switch(key_mgmt)
4870 {
4871 case WLAN_AKM_SUITE_PSK:
4872 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4873 __func__);
4874 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4875 break;
4876
4877 case WLAN_AKM_SUITE_8021X:
4878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4879 __func__);
4880 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4881 break;
4882#ifdef FEATURE_WLAN_CCX
4883#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4884#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4885 case WLAN_AKM_SUITE_CCKM:
4886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4887 __func__);
4888 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4889 break;
4890#endif
4891
4892 default:
4893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4894 __func__, key_mgmt);
4895 return -EINVAL;
4896
4897 }
4898 return 0;
4899}
4900
4901/*
4902 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4903 * This function is used to set the encryption type
4904 * (NONE/WEP40/WEP104/TKIP/CCMP).
4905 */
4906static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4907 u32 cipher,
4908 bool ucast
4909 )
4910{
4911 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4912 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4913 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4914
4915 ENTER();
4916
4917 if (!cipher)
4918 {
4919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4920 __func__, cipher);
4921 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4922 }
4923 else
4924 {
4925
4926 /*set encryption method*/
4927 switch (cipher)
4928 {
4929 case IW_AUTH_CIPHER_NONE:
4930 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4931 break;
4932
4933 case WLAN_CIPHER_SUITE_WEP40:
4934 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4935 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4936 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4937 else
4938 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4939 break;
4940
4941 case WLAN_CIPHER_SUITE_WEP104:
4942 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4943 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4944 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4945 else
4946 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4947 break;
4948
4949 case WLAN_CIPHER_SUITE_TKIP:
4950 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4951 break;
4952
4953 case WLAN_CIPHER_SUITE_CCMP:
4954 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4955 break;
4956#ifdef FEATURE_WLAN_WAPI
4957 case WLAN_CIPHER_SUITE_SMS4:
4958 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4959 break;
4960#endif
4961
4962#ifdef FEATURE_WLAN_CCX
4963 case WLAN_CIPHER_SUITE_KRK:
4964 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4965 break;
4966#endif
4967 default:
4968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4969 __func__, cipher);
4970 return -EOPNOTSUPP;
4971 }
4972 }
4973
4974 if (ucast)
4975 {
4976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4977 __func__, encryptionType);
4978 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4979 pWextState->roamProfile.EncryptionType.numEntries = 1;
4980 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4981 encryptionType;
4982 }
4983 else
4984 {
4985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4986 __func__, encryptionType);
4987 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4988 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4989 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4990 }
4991
4992 return 0;
4993}
4994
4995
4996/*
4997 * FUNCTION: wlan_hdd_cfg80211_set_ie
4998 * This function is used to parse WPA/RSN IE's.
4999 */
5000int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5001 u8 *ie,
5002 size_t ie_len
5003 )
5004{
5005 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5006 u8 *genie = ie;
5007 v_U16_t remLen = ie_len;
5008#ifdef FEATURE_WLAN_WAPI
5009 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5010 u16 *tmp;
5011 v_U16_t akmsuiteCount;
5012 int *akmlist;
5013#endif
5014 ENTER();
5015
5016 /* clear previous assocAddIE */
5017 pWextState->assocAddIE.length = 0;
5018 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5019
5020 while (remLen >= 2)
5021 {
5022 v_U16_t eLen = 0;
5023 v_U8_t elementId;
5024 elementId = *genie++;
5025 eLen = *genie++;
5026 remLen -= 2;
5027
5028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
5029 __func__, elementId, eLen);
5030
5031 switch ( elementId )
5032 {
5033 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005034 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 -07005035 {
5036 hddLog(VOS_TRACE_LEVEL_ERROR,
5037 "%s: Invalid WPA IE", __func__);
5038 return -EINVAL;
5039 }
5040 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
5041 {
5042 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5043 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
5044 __func__, eLen + 2);
5045
5046 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5047 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005048 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5049 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 VOS_ASSERT(0);
5051 return -ENOMEM;
5052 }
5053 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5054 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5055 pWextState->assocAddIE.length += eLen + 2;
5056
5057 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5058 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5059 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5060 }
5061 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5062 {
5063 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5064 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5065 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5066 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5067 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005069 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5070 P2P_OUI_TYPE_SIZE))
5071 /*Consider P2P IE, only for P2P Client */
5072 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5073 {
5074 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5075 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
5076 __func__, eLen + 2);
5077
5078 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5079 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005080 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5081 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 VOS_ASSERT(0);
5083 return -ENOMEM;
5084 }
5085 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5086 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5087 pWextState->assocAddIE.length += eLen + 2;
5088
5089 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5090 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5091 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005092#ifdef WLAN_FEATURE_WFD
5093 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5094 WFD_OUI_TYPE_SIZE))
5095 /*Consider WFD IE, only for P2P Client */
5096 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5097 {
5098 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5099 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
5100 __func__, eLen + 2);
5101
5102 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5103 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005104 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5105 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 VOS_ASSERT(0);
5107 return -ENOMEM;
5108 }
5109 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5110 // WPS IE + P2P IE + WFD IE
5111 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5112 pWextState->assocAddIE.length += eLen + 2;
5113
5114 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5115 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5116 }
5117#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005118 /* Appending HS 2.0 Indication Element in Assiciation Request */
5119 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005120 HS20_OUI_TYPE_SIZE)) )
5121 {
5122 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5123 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
5124 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005125
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005126 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5127 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005128 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5129 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005130 VOS_ASSERT(0);
5131 return -ENOMEM;
5132 }
5133 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5134 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005135
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005136 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5137 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5138 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005139
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 break;
5141 case DOT11F_EID_RSN:
5142 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5143 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5144 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5145 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5146 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5147 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005148 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5149 case DOT11F_EID_EXTCAP:
5150 {
5151 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5152 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5153 __func__, eLen + 2);
5154
5155 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5156 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005157 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5158 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005159 VOS_ASSERT(0);
5160 return -ENOMEM;
5161 }
5162 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5163 pWextState->assocAddIE.length += eLen + 2;
5164
5165 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5166 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5167 break;
5168 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005169#ifdef FEATURE_WLAN_WAPI
5170 case WLAN_EID_WAPI:
5171 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5172 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5173 pAdapter->wapi_info.nWapiMode);
5174 tmp = (u16 *)ie;
5175 tmp = tmp + 2; // Skip element Id and Len, Version
5176 akmsuiteCount = WPA_GET_LE16(tmp);
5177 tmp = tmp + 1;
5178 akmlist = (int *)(tmp);
5179 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5180 {
5181 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5182 }
5183 else
5184 {
5185 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5186 VOS_ASSERT(0);
5187 return -EINVAL;
5188 }
5189
5190 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5191 {
5192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005193 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005194 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5195 }
5196 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5197 {
5198 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005199 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5201 }
5202 break;
5203#endif
5204 default:
5205 hddLog (VOS_TRACE_LEVEL_ERROR,
5206 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005207 /* when Unknown IE is received we should break and continue
5208 * to the next IE in the buffer instead we were returning
5209 * so changing this to break */
5210 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 }
5212 genie += eLen;
5213 remLen -= eLen;
5214 }
5215 EXIT();
5216 return 0;
5217}
5218
5219/*
5220 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5221 * This function is used to initialize the security
5222 * parameters during connect operation.
5223 */
5224int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5225 struct cfg80211_connect_params *req
5226 )
5227{
5228 int status = 0;
5229 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5230 ENTER();
5231
5232 /*set wpa version*/
5233 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5234
5235 if (req->crypto.wpa_versions)
5236 {
5237 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5238 && ( (req->ie_len)
5239 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5240 // Make sure that it is including a WPA IE.
5241 /* Currently NL is putting WPA version 1 even for open,
5242 * since p2p ie is also put in same buffer.
5243 * */
5244 {
5245 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5246 }
5247 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5248 {
5249 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5250 }
5251 }
5252
5253 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5254 pWextState->wpaVersion);
5255
5256 /*set authentication type*/
5257 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5258
5259 if (0 > status)
5260 {
5261 hddLog(VOS_TRACE_LEVEL_ERROR,
5262 "%s: failed to set authentication type ", __func__);
5263 return status;
5264 }
5265
5266 /*set key mgmt type*/
5267 if (req->crypto.n_akm_suites)
5268 {
5269 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5270 if (0 > status)
5271 {
5272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5273 __func__);
5274 return status;
5275 }
5276 }
5277
5278 /*set pairwise cipher type*/
5279 if (req->crypto.n_ciphers_pairwise)
5280 {
5281 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5282 req->crypto.ciphers_pairwise[0], true);
5283 if (0 > status)
5284 {
5285 hddLog(VOS_TRACE_LEVEL_ERROR,
5286 "%s: failed to set unicast cipher type", __func__);
5287 return status;
5288 }
5289 }
5290 else
5291 {
5292 /*Reset previous cipher suite to none*/
5293 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5294 if (0 > status)
5295 {
5296 hddLog(VOS_TRACE_LEVEL_ERROR,
5297 "%s: failed to set unicast cipher type", __func__);
5298 return status;
5299 }
5300 }
5301
5302 /*set group cipher type*/
5303 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5304 false);
5305
5306 if (0 > status)
5307 {
5308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5309 __func__);
5310 return status;
5311 }
5312
5313 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5314 if (req->ie_len)
5315 {
5316 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5317 if ( 0 > status)
5318 {
5319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5320 __func__);
5321 return status;
5322 }
5323 }
5324
5325 /*incase of WEP set default key information*/
5326 if (req->key && req->key_len)
5327 {
5328 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5329 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5330 )
5331 {
5332 if ( IW_AUTH_KEY_MGMT_802_1X
5333 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5334 {
5335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5336 __func__);
5337 return -EOPNOTSUPP;
5338 }
5339 else
5340 {
5341 u8 key_len = req->key_len;
5342 u8 key_idx = req->key_idx;
5343
5344 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5345 && (CSR_MAX_NUM_KEY > key_idx)
5346 )
5347 {
5348 hddLog(VOS_TRACE_LEVEL_INFO,
5349 "%s: setting default wep key, key_idx = %hu key_len %hu",
5350 __func__, key_idx, key_len);
5351 vos_mem_copy(
5352 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5353 req->key, key_len);
5354 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5355 (u8)key_len;
5356 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5357 }
5358 }
5359 }
5360 }
5361
5362 return status;
5363}
5364
5365/*
5366 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5367 * This function is used to initialize the security
5368 * parameters during connect operation.
5369 */
5370static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5371 struct net_device *ndev,
5372 struct cfg80211_connect_params *req
5373 )
5374{
5375 int status = 0;
5376 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5377 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5378 hdd_context_t *pHddCtx = NULL;
5379
5380 ENTER();
5381
5382 hddLog(VOS_TRACE_LEVEL_INFO,
5383 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5384
5385 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5386 {
5387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5388 "%s:LOGP in Progress. Ignore!!!", __func__);
5389 return -EAGAIN;
5390 }
5391
5392#ifdef WLAN_BTAMP_FEATURE
5393 //Infra connect not supported when AMP traffic is on.
5394 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5395 {
5396 hddLog(VOS_TRACE_LEVEL_ERROR,
5397 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005398 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 }
5400#endif
5401 /*initialise security parameters*/
5402 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5403
5404 if ( 0 > status)
5405 {
5406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5407 __func__);
5408 return status;
5409 }
5410
5411 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005412 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005413 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5414 (vos_concurrent_sessions_running()))
5415 {
5416 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5417
5418 if (NULL != pVosContext)
5419 {
5420 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5421 if(NULL != pHddCtx)
5422 {
5423 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5424 }
5425 }
5426 }
5427
Mohit Khanna765234a2012-09-11 15:08:35 -07005428 if ( req->channel )
5429 {
5430 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5431 req->ssid_len, req->bssid,
5432 req->channel->hw_value);
5433 }
5434 else
5435 {
5436 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5437 req->ssid_len, req->bssid,
5438 0);
5439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005440
5441 if (0 > status)
5442 {
5443 //ReEnable BMPS if disabled
5444 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5445 (NULL != pHddCtx))
5446 {
5447 //ReEnable Bmps and Imps back
5448 hdd_enable_bmps_imps(pHddCtx);
5449 }
5450
5451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5452 return status;
5453 }
5454 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5455 EXIT();
5456 return status;
5457}
5458
5459
5460/*
5461 * FUNCTION: wlan_hdd_cfg80211_disconnect
5462 * This function is used to issue a disconnect request to SME
5463 */
5464static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5465 struct net_device *dev,
5466 u16 reason
5467 )
5468{
5469 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5470 tCsrRoamProfile *pRoamProfile =
5471 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5472 int status = 0;
5473 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005474#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005475 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005476 tANI_U8 staIdx;
5477#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005478
5479 ENTER();
5480
5481 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5482 __func__,pAdapter->device_mode);
5483
5484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5485 __func__, reason);
5486
5487 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5488 {
5489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5490 "%s:LOGP in Progress. Ignore!!!",__func__);
5491 return -EAGAIN;
5492 }
5493 if (NULL != pRoamProfile)
5494 {
5495 /*issue disconnect request to SME, if station is in connected state*/
5496 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5497 {
5498 eCsrRoamDisconnectReason reasonCode =
5499 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5500 switch(reason)
5501 {
5502 case WLAN_REASON_MIC_FAILURE:
5503 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5504 break;
5505
5506 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5507 case WLAN_REASON_DISASSOC_AP_BUSY:
5508 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5509 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5510 break;
5511
5512 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5513 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5514 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5515 break;
5516
5517 case WLAN_REASON_DEAUTH_LEAVING:
5518 default:
5519 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5520 break;
5521 }
5522 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5523 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5524 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5525
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005526#ifdef FEATURE_WLAN_TDLS
5527 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005528 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005529 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005530 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5531 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005532 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005533 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005534 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005535 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
5536 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d %02x:%02x:%02x:%02x:%02x:%02x",
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005537 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005538 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005539 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005540 pAdapter->sessionId,
5541 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005542 }
5543 }
5544#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 /*issue disconnect*/
5546 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5547 pAdapter->sessionId, reasonCode);
5548
5549 if ( 0 != status)
5550 {
5551 hddLog(VOS_TRACE_LEVEL_ERROR,
5552 "%s csrRoamDisconnect failure, returned %d \n",
5553 __func__, (int)status );
5554 return -EINVAL;
5555 }
5556
5557 wait_for_completion_interruptible_timeout(
5558 &pAdapter->disconnect_comp_var,
5559 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5560
5561
5562 /*stop tx queues*/
5563 netif_tx_disable(dev);
5564 netif_carrier_off(dev);
5565 }
5566 }
5567 else
5568 {
5569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5570 }
5571
5572 return status;
5573}
5574
5575/*
5576 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5577 * This function is used to initialize the security
5578 * settings in IBSS mode.
5579 */
5580static int wlan_hdd_cfg80211_set_privacy_ibss(
5581 hdd_adapter_t *pAdapter,
5582 struct cfg80211_ibss_params *params
5583 )
5584{
5585 int status = 0;
5586 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5587 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5588 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5589
5590 ENTER();
5591
5592 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5593
5594 if (params->ie_len && ( NULL != params->ie) )
5595 {
5596 if (WLAN_EID_RSN == params->ie[0])
5597 {
5598 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5599 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5600 }
5601 else
5602 {
5603 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5604 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5605 }
5606 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5607
5608 if (0 > status)
5609 {
5610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5611 __func__);
5612 return status;
5613 }
5614 }
5615
5616 pWextState->roamProfile.AuthType.authType[0] =
5617 pHddStaCtx->conn_info.authType =
5618 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5619
5620 if (params->privacy)
5621 {
5622 /* Security enabled IBSS, At this time there is no information available
5623 * about the security paramters, so initialise the encryption type to
5624 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5625 * The correct security parameters will be updated later in
5626 * wlan_hdd_cfg80211_add_key */
5627 /* Hal expects encryption type to be set inorder
5628 *enable privacy bit in beacons */
5629
5630 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5631 }
5632
5633 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5634 pWextState->roamProfile.EncryptionType.numEntries = 1;
5635 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5636
5637 return status;
5638}
5639
5640/*
5641 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5642 * This function is used to create/join an IBSS
5643 */
5644static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5645 struct net_device *dev,
5646 struct cfg80211_ibss_params *params
5647 )
5648{
5649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5650 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5651 tCsrRoamProfile *pRoamProfile;
5652 int status;
5653 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5654
5655 ENTER();
5656
5657 hddLog(VOS_TRACE_LEVEL_INFO,
5658 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5659
5660 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5661 {
5662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5663 "%s:LOGP in Progress. Ignore!!!", __func__);
5664 return -EAGAIN;
5665 }
5666
5667 if (NULL == pWextState)
5668 {
5669 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5670 __func__);
5671 return -EIO;
5672 }
5673
5674 pRoamProfile = &pWextState->roamProfile;
5675
5676 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5677 {
5678 hddLog (VOS_TRACE_LEVEL_ERROR,
5679 "%s Interface type is not set to IBSS \n", __func__);
5680 return -EINVAL;
5681 }
5682
5683 /* Set Channel */
5684 if (NULL != params->channel)
5685 {
5686 u8 channelNum;
5687 if (IEEE80211_BAND_5GHZ == params->channel->band)
5688 {
5689 hddLog(VOS_TRACE_LEVEL_ERROR,
5690 "%s: IBSS join is called with unsupported band %d",
5691 __func__, params->channel->band);
5692 return -EOPNOTSUPP;
5693 }
5694
5695 /* Get channel number */
5696 channelNum =
5697 ieee80211_frequency_to_channel(params->channel->center_freq);
5698
5699 /*TODO: use macro*/
5700 if (14 >= channelNum)
5701 {
5702 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5703 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5704 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5705 int indx;
5706
5707 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5708 validChan, &numChans))
5709 {
5710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5711 __func__);
5712 return -EOPNOTSUPP;
5713 }
5714
5715 for (indx = 0; indx < numChans; indx++)
5716 {
5717 if (channelNum == validChan[indx])
5718 {
5719 break;
5720 }
5721 }
5722 if (indx >= numChans)
5723 {
5724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5725 __func__, channelNum);
5726 return -EINVAL;
5727 }
5728 /* Set the Operational Channel */
5729 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5730 channelNum);
5731 pRoamProfile->ChannelInfo.numOfChannels = 1;
5732 pHddStaCtx->conn_info.operationChannel = channelNum;
5733 pRoamProfile->ChannelInfo.ChannelList =
5734 &pHddStaCtx->conn_info.operationChannel;
5735 }
5736 else
5737 {
5738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5739 __func__, channelNum);
5740 return -EINVAL;
5741 }
5742 }
5743
5744 /* Initialize security parameters */
5745 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5746 if (status < 0)
5747 {
5748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5749 __func__);
5750 return status;
5751 }
5752
5753 /* Issue connect start */
5754 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005755 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005756
5757 if (0 > status)
5758 {
5759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5760 return status;
5761 }
5762
5763 return 0;
5764}
5765
5766/*
5767 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5768 * This function is used to leave an IBSS
5769 */
5770static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5771 struct net_device *dev
5772 )
5773{
5774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5775 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5776 tCsrRoamProfile *pRoamProfile;
5777
5778 ENTER();
5779
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005780 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5781 {
5782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5783 "%s:LOGP in Progress. Ignore!!!", __func__);
5784 return -EAGAIN;
5785 }
5786
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5788 if (NULL == pWextState)
5789 {
5790 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5791 __func__);
5792 return -EIO;
5793 }
5794
5795 pRoamProfile = &pWextState->roamProfile;
5796
5797 /* Issue disconnect only if interface type is set to IBSS */
5798 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5799 {
5800 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5801 __func__);
5802 return -EINVAL;
5803 }
5804
5805 /* Issue Disconnect request */
5806 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5807 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5808 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5809
5810 return 0;
5811}
5812
5813/*
5814 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5815 * This function is used to set the phy parameters
5816 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5817 */
5818static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5819 u32 changed)
5820{
5821 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5822 tHalHandle hHal = pHddCtx->hHal;
5823
5824 ENTER();
5825
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005826 if ( pHddCtx->isLogpInProgress )
5827 {
5828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5829 "%s:LOGP in Progress. Ignore!!!", __func__);
5830 return -EAGAIN;
5831 }
5832
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5834 {
5835 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5836 WNI_CFG_RTS_THRESHOLD_STAMAX :
5837 wiphy->rts_threshold;
5838
5839 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5840 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5841 {
5842 hddLog(VOS_TRACE_LEVEL_ERROR,
5843 "%s: Invalid RTS Threshold value %hu",
5844 __func__, rts_threshold);
5845 return -EINVAL;
5846 }
5847
5848 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5849 rts_threshold, ccmCfgSetCallback,
5850 eANI_BOOLEAN_TRUE))
5851 {
5852 hddLog(VOS_TRACE_LEVEL_ERROR,
5853 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5854 __func__, rts_threshold);
5855 return -EIO;
5856 }
5857
5858 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5859 rts_threshold);
5860 }
5861
5862 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5863 {
5864 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5865 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5866 wiphy->frag_threshold;
5867
5868 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5869 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5870 {
5871 hddLog(VOS_TRACE_LEVEL_ERROR,
5872 "%s: Invalid frag_threshold value %hu", __func__,
5873 frag_threshold);
5874 return -EINVAL;
5875 }
5876
5877 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5878 frag_threshold, ccmCfgSetCallback,
5879 eANI_BOOLEAN_TRUE))
5880 {
5881 hddLog(VOS_TRACE_LEVEL_ERROR,
5882 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5883 __func__, frag_threshold);
5884 return -EIO;
5885 }
5886
5887 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5888 frag_threshold);
5889 }
5890
5891 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5892 || (changed & WIPHY_PARAM_RETRY_LONG))
5893 {
5894 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5895 wiphy->retry_short :
5896 wiphy->retry_long;
5897
5898 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5899 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5900 {
5901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5902 __func__, retry_value);
5903 return -EINVAL;
5904 }
5905
5906 if (changed & WIPHY_PARAM_RETRY_SHORT)
5907 {
5908 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5909 retry_value, ccmCfgSetCallback,
5910 eANI_BOOLEAN_TRUE))
5911 {
5912 hddLog(VOS_TRACE_LEVEL_ERROR,
5913 "%s: ccmCfgSetInt failed for long retry count %hu",
5914 __func__, retry_value);
5915 return -EIO;
5916 }
5917 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5918 __func__, retry_value);
5919 }
5920 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5921 {
5922 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5923 retry_value, ccmCfgSetCallback,
5924 eANI_BOOLEAN_TRUE))
5925 {
5926 hddLog(VOS_TRACE_LEVEL_ERROR,
5927 "%s: ccmCfgSetInt failed for short retry count %hu",
5928 __func__, retry_value);
5929 return -EIO;
5930 }
5931 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5932 __func__, retry_value);
5933 }
5934 }
5935
5936 return 0;
5937}
5938
5939/*
5940 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5941 * This function is used to set the txpower
5942 */
5943static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5944#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5945 enum tx_power_setting type,
5946#else
5947 enum nl80211_tx_power_setting type,
5948#endif
5949 int dbm)
5950{
5951 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5952 tHalHandle hHal = pHddCtx->hHal;
5953 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5954 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5955
5956 ENTER();
5957
5958 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5959 dbm, ccmCfgSetCallback,
5960 eANI_BOOLEAN_TRUE))
5961 {
5962 hddLog(VOS_TRACE_LEVEL_ERROR,
5963 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5964 return -EIO;
5965 }
5966
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005967 if ( pHddCtx->isLogpInProgress )
5968 {
5969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5970 "%s:LOGP in Progress. Ignore!!!", __func__);
5971 return -EAGAIN;
5972 }
5973
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5975 dbm);
5976
5977 switch(type)
5978 {
5979 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5980 /* Fall through */
5981 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5982 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5983 {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5985 __func__);
5986 return -EIO;
5987 }
5988 break;
5989 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5991 __func__);
5992 return -EOPNOTSUPP;
5993 break;
5994 default:
5995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5996 __func__, type);
5997 return -EIO;
5998 }
5999
6000 return 0;
6001}
6002
6003/*
6004 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6005 * This function is used to read the txpower
6006 */
6007static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6008{
6009
6010 hdd_adapter_t *pAdapter;
6011 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6012
Jeff Johnsone7245742012-09-05 17:12:55 -07006013 ENTER();
6014
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 if (NULL == pHddCtx)
6016 {
6017 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6018 *dbm = 0;
6019 return -ENOENT;
6020 }
6021
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006022 if ( pHddCtx->isLogpInProgress )
6023 {
6024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6025 "%s:LOGP in Progress. Ignore!!!", __func__);
6026 return -EAGAIN;
6027 }
6028
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6030 if (NULL == pAdapter)
6031 {
6032 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6033 return -ENOENT;
6034 }
6035
6036 wlan_hdd_get_classAstats(pAdapter);
6037 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6038
Jeff Johnsone7245742012-09-05 17:12:55 -07006039 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 return 0;
6041}
6042
6043static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6044 u8* mac, struct station_info *sinfo)
6045{
6046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6047 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6048 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6049 tANI_U8 rate_flags;
6050
6051 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6052 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006053
6054 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6055 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6056 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6057 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6058 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6059 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6060 tANI_U16 maxRate = 0;
6061 tANI_U16 myRate;
6062 tANI_U16 currentRate = 0;
6063 tANI_U8 maxSpeedMCS = 0;
6064 tANI_U8 maxMCSIdx = 0;
6065 tANI_U8 rateFlag = 1;
6066 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006067 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006068
Jeff Johnsone7245742012-09-05 17:12:55 -07006069 ENTER();
6070
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6072 (0 == ssidlen))
6073 {
6074 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6075 " Invalid ssidlen, %d", __func__, ssidlen);
6076 /*To keep GUI happy*/
6077 return 0;
6078 }
6079
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006080 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6081 {
6082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6083 "%s:LOGP in Progress. Ignore!!!", __func__);
6084 return -EAGAIN;
6085 }
6086
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6088 sinfo->filled |= STATION_INFO_SIGNAL;
6089
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006090 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6092
6093 //convert to the UI units of 100kbps
6094 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6095
6096#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006097 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 -07006098 sinfo->signal,
6099 pCfg->reportMaxLinkSpeed,
6100 myRate,
6101 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006102 (int) pCfg->linkSpeedRssiMid,
6103 (int) pCfg->linkSpeedRssiLow,
6104 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006105#endif //LINKSPEED_DEBUG_ENABLED
6106
6107 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6108 {
6109 // we do not want to necessarily report the current speed
6110 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6111 {
6112 // report the max possible speed
6113 rssidx = 0;
6114 }
6115 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6116 {
6117 // report the max possible speed with RSSI scaling
6118 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6119 {
6120 // report the max possible speed
6121 rssidx = 0;
6122 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006123 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 {
6125 // report middle speed
6126 rssidx = 1;
6127 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006128 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6129 {
6130 // report middle speed
6131 rssidx = 2;
6132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 else
6134 {
6135 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006136 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 }
6138 }
6139 else
6140 {
6141 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6142 hddLog(VOS_TRACE_LEVEL_ERROR,
6143 "%s: Invalid value for reportMaxLinkSpeed: %u",
6144 __func__, pCfg->reportMaxLinkSpeed);
6145 rssidx = 0;
6146 }
6147
6148 maxRate = 0;
6149
6150 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306151 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6152 OperationalRates, &ORLeng))
6153 {
6154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6155 /*To keep GUI happy*/
6156 return 0;
6157 }
6158
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 for (i = 0; i < ORLeng; i++)
6160 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006161 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006162 {
6163 /* Validate Rate Set */
6164 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6165 {
6166 currentRate = supported_data_rate[j].supported_rate[rssidx];
6167 break;
6168 }
6169 }
6170 /* Update MAX rate */
6171 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6172 }
6173
6174 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306175 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6176 ExtendedRates, &ERLeng))
6177 {
6178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6179 /*To keep GUI happy*/
6180 return 0;
6181 }
6182
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 for (i = 0; i < ERLeng; i++)
6184 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006185 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 {
6187 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[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 MCS Rate Set -- but only if we are connected at MCS
6198 rates or if we are always reporting max speed or if we have
6199 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006200 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306202 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6203 MCSRates, &MCSLeng))
6204 {
6205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6206 /*To keep GUI happy*/
6207 return 0;
6208 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 rateFlag = 0;
6210 if (rate_flags & eHAL_TX_RATE_HT40)
6211 {
6212 rateFlag |= 1;
6213 }
6214 if (rate_flags & eHAL_TX_RATE_SGI)
6215 {
6216 rateFlag |= 2;
6217 }
6218
6219 for (i = 0; i < MCSLeng; i++)
6220 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006221 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6222 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 {
6224 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6225 {
6226 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6227 break;
6228 }
6229 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006230 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 {
6232 maxRate = currentRate;
6233 maxSpeedMCS = 1;
6234 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6235 }
6236 }
6237 }
6238
6239 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006240 if (((maxRate < myRate) && (0 == rssidx)) ||
6241 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 {
6243 maxRate = myRate;
6244 if (rate_flags & eHAL_TX_RATE_LEGACY)
6245 {
6246 maxSpeedMCS = 0;
6247 }
6248 else
6249 {
6250 maxSpeedMCS = 1;
6251 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6252 }
6253 }
6254
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006255 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 {
6257 sinfo->txrate.legacy = maxRate;
6258#ifdef LINKSPEED_DEBUG_ENABLED
6259 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6260#endif //LINKSPEED_DEBUG_ENABLED
6261 }
6262 else
6263 {
6264 sinfo->txrate.mcs = maxMCSIdx;
6265 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6266 if (rate_flags & eHAL_TX_RATE_SGI)
6267 {
6268 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6269 }
6270 if (rate_flags & eHAL_TX_RATE_HT40)
6271 {
6272 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6273 }
6274#ifdef LINKSPEED_DEBUG_ENABLED
6275 pr_info("Reporting MCS rate %d flags %x\n",
6276 sinfo->txrate.mcs,
6277 sinfo->txrate.flags );
6278#endif //LINKSPEED_DEBUG_ENABLED
6279 }
6280 }
6281 else
6282 {
6283 // report current rate instead of max rate
6284
6285 if (rate_flags & eHAL_TX_RATE_LEGACY)
6286 {
6287 //provide to the UI in units of 100kbps
6288 sinfo->txrate.legacy = myRate;
6289#ifdef LINKSPEED_DEBUG_ENABLED
6290 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6291#endif //LINKSPEED_DEBUG_ENABLED
6292 }
6293 else
6294 {
6295 //must be MCS
6296 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6297 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6298 if (rate_flags & eHAL_TX_RATE_SGI)
6299 {
6300 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6301 }
6302 if (rate_flags & eHAL_TX_RATE_HT40)
6303 {
6304 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6305 }
6306#ifdef LINKSPEED_DEBUG_ENABLED
6307 pr_info("Reporting actual MCS rate %d flags %x\n",
6308 sinfo->txrate.mcs,
6309 sinfo->txrate.flags );
6310#endif //LINKSPEED_DEBUG_ENABLED
6311 }
6312 }
6313 sinfo->filled |= STATION_INFO_TX_BITRATE;
6314
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006315 sinfo->tx_packets =
6316 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6317 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6318 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6319 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6320
6321 sinfo->tx_retries =
6322 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6323 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6324 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6325 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6326
6327 sinfo->tx_failed =
6328 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6329 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6330 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6331 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6332
6333 sinfo->filled |=
6334 STATION_INFO_TX_PACKETS |
6335 STATION_INFO_TX_RETRIES |
6336 STATION_INFO_TX_FAILED;
6337
6338 EXIT();
6339 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006340}
6341
6342static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6343 struct net_device *dev, bool mode, v_SINT_t timeout)
6344{
6345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6346 VOS_STATUS vos_status;
6347
Jeff Johnsone7245742012-09-05 17:12:55 -07006348 ENTER();
6349
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 if (NULL == pAdapter)
6351 {
6352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6353 return -ENODEV;
6354 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006355 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6356 {
6357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6358 "%s:LOGP in Progress. Ignore!!!", __func__);
6359 return -EAGAIN;
6360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006361
6362 /**The get power cmd from the supplicant gets updated by the nl only
6363 *on successful execution of the function call
6364 *we are oppositely mapped w.r.t mode in the driver
6365 **/
6366 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6367
Jeff Johnsone7245742012-09-05 17:12:55 -07006368 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 if (VOS_STATUS_E_FAILURE == vos_status)
6370 {
6371 return -EINVAL;
6372 }
6373 return 0;
6374}
6375
6376
6377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6378static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6379 struct net_device *netdev,
6380 u8 key_index)
6381{
Jeff Johnsone7245742012-09-05 17:12:55 -07006382 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 return 0;
6384}
6385#endif //LINUX_VERSION_CODE
6386
6387#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6388static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6389 struct net_device *dev,
6390 struct ieee80211_txq_params *params)
6391{
Jeff Johnsone7245742012-09-05 17:12:55 -07006392 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 return 0;
6394}
6395#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6396static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6397 struct ieee80211_txq_params *params)
6398{
Jeff Johnsone7245742012-09-05 17:12:55 -07006399 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 return 0;
6401}
6402#endif //LINUX_VERSION_CODE
6403
6404static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6405 struct net_device *dev, u8 *mac)
6406{
6407 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006408 VOS_STATUS vos_status;
6409 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006410
Jeff Johnsone7245742012-09-05 17:12:55 -07006411 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6413 {
6414 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6415 return -EINVAL;
6416 }
6417
6418 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6419 {
6420 hddLog( LOGE,
6421 "%s: Wlan Load/Unload is in progress", __func__);
6422 return -EBUSY;
6423 }
6424
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006425 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6426 {
6427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6428 "%s:LOGP in Progress. Ignore!!!", __func__);
6429 return -EAGAIN;
6430 }
6431
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 )
6435 {
6436 if( NULL == mac )
6437 {
6438 v_U16_t i;
6439 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6440 {
6441 if(pAdapter->aStaInfo[i].isUsed)
6442 {
6443 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6444 hddLog(VOS_TRACE_LEVEL_INFO,
6445 "%s: Delete STA with MAC::"
6446 "%02x:%02x:%02x:%02x:%02x:%02x",
6447 __func__,
6448 macAddr[0], macAddr[1], macAddr[2],
6449 macAddr[3], macAddr[4], macAddr[5]);
6450 hdd_softap_sta_deauth(pAdapter, macAddr);
6451 }
6452 }
6453 }
6454 else
6455 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006456
6457 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6458 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6459 {
6460 hddLog(VOS_TRACE_LEVEL_INFO,
6461 "%s: Skip this DEL STA as this is not used::"
6462 "%02x:%02x:%02x:%02x:%02x:%02x",
6463 __func__,
6464 mac[0], mac[1], mac[2],
6465 mac[3], mac[4], mac[5]);
6466 return -ENOENT;
6467 }
6468
6469 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6470 {
6471 hddLog(VOS_TRACE_LEVEL_INFO,
6472 "%s: Skip this DEL STA as deauth is in progress::"
6473 "%02x:%02x:%02x:%02x:%02x:%02x",
6474 __func__,
6475 mac[0], mac[1], mac[2],
6476 mac[3], mac[4], mac[5]);
6477 return -ENOENT;
6478 }
6479
6480 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6481
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 hddLog(VOS_TRACE_LEVEL_INFO,
6483 "%s: Delete STA with MAC::"
6484 "%02x:%02x:%02x:%02x:%02x:%02x",
6485 __func__,
6486 mac[0], mac[1], mac[2],
6487 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006488
6489 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6490 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6491 {
6492 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6493 hddLog(VOS_TRACE_LEVEL_INFO,
6494 "%s: STA removal failed for ::"
6495 "%02x:%02x:%02x:%02x:%02x:%02x",
6496 __func__,
6497 mac[0], mac[1], mac[2],
6498 mac[3], mac[4], mac[5]);
6499 return -ENOENT;
6500 }
6501
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 }
6503 }
6504
6505 EXIT();
6506
6507 return 0;
6508}
6509
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006510static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6511 struct net_device *dev, u8 *mac, struct station_parameters *params)
6512{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006513 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006514#ifdef FEATURE_WLAN_TDLS
6515 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006516 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006517 mask = params->sta_flags_mask;
6518
6519 set = params->sta_flags_set;
6520
Lee Hoonkic1262f22013-01-24 21:59:00 -08006521 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6522 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006523
6524 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6525 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006526 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006527 }
6528 }
6529#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006530 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006531}
6532
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006533
6534#ifdef FEATURE_WLAN_LFR
6535static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006536 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006537{
6538#define MAX_PMKSAIDS_IN_CACHE 8
6539 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006540 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006541 tANI_U32 j=0;
6542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6543 tHalHandle halHandle;
6544 eHalStatus result;
6545 tANI_U8 BSSIDMatched = 0;
6546
Jeff Johnsone7245742012-09-05 17:12:55 -07006547 ENTER();
6548
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006549 // Validate pAdapter
6550 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6551 {
6552 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6553 return -EINVAL;
6554 }
6555
6556 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6557 {
6558 hddLog( LOGE,
6559 "%s: Wlan Load/Unload is in progress", __func__);
6560 return -EBUSY;
6561 }
6562
6563 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6564 {
6565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6566 "%s:LOGP in Progress. Ignore!!!", __func__);
6567 return -EAGAIN;
6568 }
6569
6570 // Retrieve halHandle
6571 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6572
6573 for (j = 0; j < i; j++)
6574 {
6575 if(vos_mem_compare(PMKIDCache[j].BSSID,
6576 pmksa->bssid, WNI_CFG_BSSID_LEN))
6577 {
6578 /* BSSID matched previous entry. Overwrite it. */
6579 BSSIDMatched = 1;
6580 vos_mem_copy(PMKIDCache[j].BSSID,
6581 pmksa->bssid, WNI_CFG_BSSID_LEN);
6582 vos_mem_copy(PMKIDCache[j].PMKID,
6583 pmksa->pmkid,
6584 CSR_RSN_PMKID_SIZE);
6585 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006586 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006587 dump_bssid(pmksa->bssid);
6588 dump_pmkid(halHandle, pmksa->pmkid);
6589 break;
6590 }
6591 }
6592
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006593 /* Check we compared all entries,if then take the first slot now */
6594 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6595
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006596 if (!BSSIDMatched)
6597 {
6598 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6599 vos_mem_copy(PMKIDCache[i].BSSID,
6600 pmksa->bssid, ETHER_ADDR_LEN);
6601 vos_mem_copy(PMKIDCache[i].PMKID,
6602 pmksa->pmkid,
6603 CSR_RSN_PMKID_SIZE);
6604 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006605 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006606 dump_bssid(pmksa->bssid);
6607 dump_pmkid(halHandle, pmksa->pmkid);
6608 // Increment the HDD Local Cache index
6609 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6610 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6611 }
6612
6613
6614 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6615 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006616 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006617 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006618 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006619 // Finally set the PMKSA ID Cache in CSR
6620 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6621 PMKIDCache,
6622 i );
6623 return 0;
6624}
6625
6626
6627static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006628 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006629{
Jeff Johnsone7245742012-09-05 17:12:55 -07006630 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006631 // TODO: Implement this later.
6632 return 0;
6633}
6634
6635static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6636{
Jeff Johnsone7245742012-09-05 17:12:55 -07006637 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006638 // TODO: Implement this later.
6639 return 0;
6640}
6641#endif
6642
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006643#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6644static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6645 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6646{
6647 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6648 hdd_station_ctx_t *pHddStaCtx;
6649
6650 if (NULL == pAdapter)
6651 {
6652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6653 return -ENODEV;
6654 }
6655
6656 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6657
6658 // Added for debug on reception of Re-assoc Req.
6659 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6660 {
6661 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6662 ftie->ie_len);
6663 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6664 }
6665
6666#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6667 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6668 ftie->ie_len);
6669#endif
6670
6671 // Pass the received FT IEs to SME
6672 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6673 ftie->ie_len);
6674 return 0;
6675}
6676#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006677
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006678#ifdef FEATURE_WLAN_TDLS
6679static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6680 u8 *peer, u8 action_code, u8 dialog_token,
6681 u16 status_code, const u8 *buf, size_t len)
6682{
6683
6684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6685 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006686 u8 peerMac[6];
6687 VOS_STATUS status;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006688 int ret = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006689 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006690
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006691 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006692 {
6693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6694 "Invalid arguments");
6695 return -EINVAL;
6696 }
6697
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006698 if (pHddCtx->isLogpInProgress)
6699 {
6700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6701 "%s:LOGP in Progress. Ignore!!!", __func__);
6702 return -EBUSY;
6703 }
6704
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006705 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006706 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6707 {
6708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6709 "TDLS Disabled in INI OR not enabled in FW.\
6710 Cannot process TDLS commands \n");
6711 return -ENOTSUPP;
6712 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006713
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006714 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
6715 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006716 if (wlan_hdd_tdls_is_progress(pAdapter, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006717 {
6718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6719 "%s: TDLS setup is ongoing. Request declined.", __func__);
6720 return -EPERM;
6721 }
6722 }
6723
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006724 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
6725 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08006726 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006727 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006728 {
6729 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6730 we return error code at 'add_station()'. Hence we have this
6731 check again in addtion to add_station().
6732 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006733 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006734 {
6735 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6736 "%s: TDLS Max peer already connected. Request declined. \n",
6737 __func__);
6738 return -EPERM;
6739 }
6740 else
6741 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006742 /* maximum reached. tweak to send error code to peer and return
6743 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006744 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6745 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6746 "%s: TDLS Max peer already connected send response status %d \n",
6747 __func__,status_code);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006748 ret = -EPERM;
6749 /* fall through to send setup resp with failure status
6750 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006751 }
6752 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006753 else
6754 {
6755 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006756 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006757 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
6758 {
6759 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6760 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
6761 __func__, peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6762 return -EPERM;
6763 }
6764 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006765 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006766 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006767
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006768#ifdef WLAN_FEATURE_TDLS_DEBUG
6769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6770 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6771 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6772 action_code, dialog_token, status_code, len);
6773#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006774
Hoonki Leea34dd892013-02-05 22:56:02 -08006775 /*Except teardown responder will not be used so just make 0*/
6776 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006777 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08006778 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006779 responder = wlan_hdd_tdls_get_responder(pAdapter, peerMac);
6780 if(-1 == responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08006781 {
6782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6783 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6784 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6785 dialog_token, status_code, len);
6786 return -EPERM;
6787 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006788 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006789
Pervinder Singhb4638422013-03-04 22:51:36 -08006790 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006791 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006792 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_CONNECTING);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006793
6794 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
6795
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006796 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006797 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006798
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006799 if (VOS_STATUS_SUCCESS != status)
6800 {
6801 if(ret == 0 && /* if failure, don't need to set the progress bit */
6802 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006803 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006804
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6806 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006807 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006808 }
6809
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006810 /* not block discovery request, as it is called from timer callback */
6811 if (SIR_MAC_TDLS_DIS_REQ != action_code)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006812 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006813 long rc;
6814
6815 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006816 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006817
Pervinder Singhb4638422013-03-04 22:51:36 -08006818 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006819 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006820 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab88f6772013-02-27 18:12:56 -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_IDLE);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006823
6824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pervinder Singhb4638422013-03-04 22:51:36 -08006825 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
6826 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006827 return -EPERM;
6828 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006829 }
6830
6831 if (ret)
6832 return ret;
6833
Hoonki Leea34dd892013-02-05 22:56:02 -08006834 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6835 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006836 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006837 }
6838 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6839 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006840 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006841 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006842
6843 return 0;
6844}
6845
6846static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6847 u8 *peer, enum nl80211_tdls_operation oper)
6848{
6849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006851#ifdef WLAN_FEATURE_TDLS_DEBUG
6852 const char *tdls_oper_str[]= {
6853 "NL80211_TDLS_DISCOVERY_REQ",
6854 "NL80211_TDLS_SETUP",
6855 "NL80211_TDLS_TEARDOWN",
6856 "NL80211_TDLS_ENABLE_LINK",
6857 "NL80211_TDLS_DISABLE_LINK",
6858 "NL80211_TDLS_UNKONW_OPER"};
6859#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006860
6861 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6862 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006864 "Invalid arguments");
6865 return -EINVAL;
6866 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006867
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006868 if (pHddCtx->isLogpInProgress)
6869 {
6870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6871 "%s:LOGP in Progress. Ignore!!!", __func__);
6872 return -EBUSY;
6873 }
6874
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006875#ifdef WLAN_FEATURE_TDLS_DEBUG
6876 if((int)oper > 4)
6877 oper = 5;
6878
6879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6880 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6881 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6882 tdls_oper_str[(int)oper]);
6883#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006884
6885 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006886 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006887 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006889 "TDLS Disabled in INI OR not enabled in FW.\
6890 Cannot process TDLS commands \n");
6891 return -ENOTSUPP;
6892 }
6893
6894 switch (oper) {
6895 case NL80211_TDLS_ENABLE_LINK:
6896 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006897 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006898 VOS_STATUS status;
6899
6900 if (peer) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006901 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006902
6903 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006904 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006905 __func__, peer[0], peer[1],
6906 peer[2], peer[3],
6907 peer[4], peer[5] );
6908
Hoonki Lee387663d2013-02-05 18:08:43 -08006909 if ( NULL == pTdlsPeer ) {
6910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6911 __func__, peer[0], peer[1],
6912 peer[2], peer[3],
6913 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006914 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006915 }
6916
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006917 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
6918 {
6919 /* start TDLS client registration with TL */
6920 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006921 wlan_hdd_tdls_increment_peer_count(pAdapter);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006922 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006923 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006924 }
Chilam NG571c65a2013-01-19 12:27:36 +05306925
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006926 } else {
6927 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6928 }
6929 }
6930 break;
6931 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006932 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006933 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006934
6935 if(NULL != curr_peer)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006936 {
6937 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6938 pAdapter->sessionId, peer );
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006939 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08006940 }
6941 else
6942 {
6943 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6944 "%s: TDLS Peer Station doesn't exist \n",__func__);
6945 }
6946 return 0;
6947 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006948 case NL80211_TDLS_TEARDOWN:
6949 case NL80211_TDLS_SETUP:
6950 case NL80211_TDLS_DISCOVERY_REQ:
6951 /* We don't support in-driver setup/teardown/discovery */
6952 return -ENOTSUPP;
6953 default:
6954 return -ENOTSUPP;
6955 }
6956 return 0;
6957}
Chilam NG571c65a2013-01-19 12:27:36 +05306958
6959int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6960 struct net_device *dev, u8 *peer)
6961{
6962 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6963 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6964
6965 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6966 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6967}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006968#endif
6969
Jeff Johnson295189b2012-06-20 16:38:30 -07006970/* cfg80211_ops */
6971static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6972{
6973 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6974 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6975 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6976 .change_station = wlan_hdd_change_station,
6977#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6978 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6979 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6980 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006981#else
6982 .start_ap = wlan_hdd_cfg80211_start_ap,
6983 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6984 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006985#endif
6986 .change_bss = wlan_hdd_cfg80211_change_bss,
6987 .add_key = wlan_hdd_cfg80211_add_key,
6988 .get_key = wlan_hdd_cfg80211_get_key,
6989 .del_key = wlan_hdd_cfg80211_del_key,
6990 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006991#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 .scan = wlan_hdd_cfg80211_scan,
6995 .connect = wlan_hdd_cfg80211_connect,
6996 .disconnect = wlan_hdd_cfg80211_disconnect,
6997 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6998 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6999 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7000 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7001 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7003 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7004 .mgmt_tx = wlan_hdd_action,
7005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7006 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7007 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7008 .set_txq_params = wlan_hdd_set_txq_params,
7009#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007010 .get_station = wlan_hdd_cfg80211_get_station,
7011 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7012 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007013 .add_station = wlan_hdd_cfg80211_add_station,
7014#ifdef FEATURE_WLAN_LFR
7015 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7016 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7017 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7018#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007019#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7020 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7021#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007022#ifdef FEATURE_WLAN_TDLS
7023 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7024 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007026};
7027