blob: 42a87f61f471805b0dbc59ad0eb2a9816bb76574 [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 Nakkala681989c2013-03-06 22:27:48 -08002781 tCsrStaParams StaParams = {0};
2782 u32 set;
2783 tANI_U8 isBufSta = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002784 ENTER();
2785
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002786 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2787 {
2788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2789 "%s:LOGP in Progress. Ignore!!!", __func__);
2790 return -EAGAIN;
2791 }
2792
Jeff Johnson295189b2012-06-20 16:38:30 -07002793 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2794
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002795 StaParams.capability = params->capability;
2796 StaParams.uapsd_queues = params->uapsd_queues;
2797 StaParams.max_sp = params->max_sp;
2798
2799 if (0 != params->ext_capab_len)
2800 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2801 sizeof(StaParams.extn_capability));
2802
2803 if (NULL != params->ht_capa)
2804 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
2805
2806 StaParams.supported_rates_len = params->supported_rates_len;
2807
2808 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2809 * The supported_rates array , for all the structures propogating till Add Sta
2810 * to the firmware has to be modified , if the supplicant (ieee80211) is
2811 * modified to send more rates.
2812 */
2813
2814 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2815 */
2816 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2817 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2818
2819 if (0 != StaParams.supported_rates_len) {
2820 int i = 0;
2821 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2822 StaParams.supported_rates_len);
2823 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2824 "Supported Rates with Length %d", StaParams.supported_rates_len);
2825 for (i=0; i < StaParams.supported_rates_len; i++)
2826 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2827 "[%d]: %0x", i, StaParams.supported_rates[i]);
2828 }
2829
2830 if (NULL != params->vht_capa)
2831 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
2832
2833 set = params->sta_flags_set;
2834
2835 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2836 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002837 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002838 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002839 {
2840 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2841 WLANTL_STA_AUTHENTICATED);
2842
2843 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002844 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002845 return -EINVAL;
2846 }
2847 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002848 else if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ) {
2849 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2850 if (0 != params->ext_capab_len ) {
2851 /*Define A Macro : TODO Sunil*/
2852 if ((1<<4) & StaParams.extn_capability[3]) {
2853 isBufSta = 1;
2854 }
2855 }
2856 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2857 "%s: TDLS Peer Parameters.", __func__);
2858 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2859 "uapsd_queues: %0x\n", params->uapsd_queues);
2860 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2861 "max_sp: %0x\n", params->max_sp);
2862 if (params->ht_capa) {
2863 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2864 "ht_capa->cap_info: %0x\n", params->ht_capa->cap_info);
2865 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2866 "ht_capa->ampdu_params_info: %0x\n",
2867 params->ht_capa->ampdu_params_info);
2868 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2869 "ht_capa->extended_capabilities: %0x\n",
2870 params->ht_capa->extended_ht_cap_info);
2871 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2872 "ht_capa->tx_BF_cap_info: %0x\n",
2873 params->ht_capa->tx_BF_cap_info);
2874 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2875 "ht_capa->antenna_selection_info: %0x\n",
2876 params->ht_capa->antenna_selection_info);
2877 }
2878 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2879 "params->capability: %0x\n",params->capability);
2880 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2881 "params->ext_capab_len: %0x\n",params->ext_capab_len);
2882 if (0 != params->ext_capab_len )
2883 {
2884 int i =0;
2885 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2886 "Extended capabilities:");
2887 for (i=0; i < params->ext_capab_len; i++)
2888 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2889 "[%d]: %0x", i, params->ext_capab[i]);
2890 }
2891 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
2892 // params->max_sp, isBufSta);
2893 if (VOS_STATUS_SUCCESS != status) {
2894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2895 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
2896 return -EINVAL;
2897 }
2898 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2899 "ht_capa->cap_info: %0x\n", StaParams.HTCap.capInfo);
2900 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
2901
2902 if (VOS_STATUS_SUCCESS != status) {
2903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2904 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
2905 return -EINVAL;
2906 }
2907 }
2908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002909
Jeff Johnsone7245742012-09-05 17:12:55 -07002910 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 return status;
2912}
2913
2914/*
2915 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2916 * This function is used to get peer station index in IBSS mode
2917 */
2918static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2919{
2920 u8 idx = 0;
2921 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2922 ENTER();
2923 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2924 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2925 {
2926 if ( (0 !=
2927 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2928 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2929 temp, VOS_MAC_ADDR_SIZE)
2930 )
2931 {
2932 return idx;
2933 }
2934 }
2935 return idx;
2936}
2937
2938
2939/*
2940 * FUNCTION: wlan_hdd_cfg80211_add_key
2941 * This function is used to initialize the key information
2942 */
2943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2944static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2945 struct net_device *ndev,
2946 u8 key_index, bool pairwise,
2947 const u8 *mac_addr,
2948 struct key_params *params
2949 )
2950#else
2951static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2952 struct net_device *ndev,
2953 u8 key_index, const u8 *mac_addr,
2954 struct key_params *params
2955 )
2956#endif
2957{
2958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2959 tCsrRoamSetKey setKey;
2960 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2961 int status = 0;
2962 v_U32_t roamId= 0xFF;
2963 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2964 hdd_hostapd_state_t *pHostapdState;
2965 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002966 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002967
2968 ENTER();
2969
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002970 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2971 {
2972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2973 "%s:LOGP in Progress. Ignore!!!", __func__);
2974 return -EAGAIN;
2975 }
2976
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2978 __func__,pAdapter->device_mode);
2979
2980 if (CSR_MAX_NUM_KEY <= key_index)
2981 {
2982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2983 key_index);
2984
2985 return -EINVAL;
2986 }
2987
2988 hddLog(VOS_TRACE_LEVEL_INFO,
2989 "%s: called with key index = %d & key length %d",
2990 __func__, key_index, params->key_len);
2991
2992 /*extract key idx, key len and key*/
2993 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2994 setKey.keyId = key_index;
2995 setKey.keyLength = params->key_len;
2996 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2997
2998 switch (params->cipher)
2999 {
3000 case WLAN_CIPHER_SUITE_WEP40:
3001 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3002 break;
3003
3004 case WLAN_CIPHER_SUITE_WEP104:
3005 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3006 break;
3007
3008 case WLAN_CIPHER_SUITE_TKIP:
3009 {
3010 u8 *pKey = &setKey.Key[0];
3011 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3012
3013 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3014
3015 /*Supplicant sends the 32bytes key in this order
3016
3017 |--------------|----------|----------|
3018 | Tk1 |TX-MIC | RX Mic |
3019 |--------------|----------|----------|
3020 <---16bytes---><--8bytes--><--8bytes-->
3021
3022 */
3023 /*Sme expects the 32 bytes key to be in the below order
3024
3025 |--------------|----------|----------|
3026 | Tk1 |RX-MIC | TX Mic |
3027 |--------------|----------|----------|
3028 <---16bytes---><--8bytes--><--8bytes-->
3029 */
3030 /* Copy the Temporal Key 1 (TK1) */
3031 vos_mem_copy(pKey, params->key,16);
3032
3033 /*Copy the rx mic first*/
3034 vos_mem_copy(&pKey[16],&params->key[24],8);
3035
3036 /*Copy the tx mic */
3037 vos_mem_copy(&pKey[24],&params->key[16],8);
3038
3039
3040 break;
3041 }
3042
3043 case WLAN_CIPHER_SUITE_CCMP:
3044 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3045 break;
3046
3047#ifdef FEATURE_WLAN_WAPI
3048 case WLAN_CIPHER_SUITE_SMS4:
3049 {
3050 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3051 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3052 params->key, params->key_len);
3053 return 0;
3054 }
3055#endif
3056#ifdef FEATURE_WLAN_CCX
3057 case WLAN_CIPHER_SUITE_KRK:
3058 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3059 break;
3060#endif
3061 default:
3062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3063 __func__, params->cipher);
3064 return -EOPNOTSUPP;
3065 }
3066
3067 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3068 __func__, setKey.encType);
3069
3070
3071
3072 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003073 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003074 )
3075 {
3076
3077
3078 if (
3079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3080 (!pairwise)
3081#else
3082 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3083#endif
3084 )
3085 {
3086 /* set group key*/
3087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003088 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 __func__, __LINE__);
3090 setKey.keyDirection = eSIR_RX_ONLY;
3091 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3092 }
3093 else
3094 {
3095 /* set pairwise key*/
3096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3097 "%s- %d: setting pairwise key",
3098 __func__, __LINE__);
3099 setKey.keyDirection = eSIR_TX_RX;
3100 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3101 }
3102
3103 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3104 if( pHostapdState->bssState == BSS_START )
3105 {
3106 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3107
3108 if ( status != eHAL_STATUS_SUCCESS )
3109 {
3110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3111 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3112 __LINE__, status );
3113 }
3114 }
3115
3116 /* Saving WEP keys */
3117 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3118 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3119 {
3120 //Save the wep key in ap context. Issue setkey after the BSS is started.
3121 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3122 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3123 }
3124 else
3125 {
3126 //Save the 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->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3129 }
3130 }
3131 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003132 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003133 )
3134 {
3135 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3136 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3137
3138 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3139
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003140 pWextState->roamProfile.Keys.defaultIndex = key_index;
3141
3142
Jeff Johnson295189b2012-06-20 16:38:30 -07003143 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3144 params->key, params->key_len);
3145
3146 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3147
3148 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3149 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3150 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3151 )
3152 &&
3153 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3154 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3155 )
3156 )
3157 {
3158 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3159 * interface, copy bssid for pairwise key and group macaddr for
3160 * group key initialization*/
3161
3162 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3163
3164 pWextState->roamProfile.negotiatedUCEncryptionType =
3165 pHddStaCtx->conn_info.ucEncryptionType =
3166 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3167 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3168 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3169
3170
3171 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3172 "%s: Negotiated encryption type %d", __func__,
3173 pWextState->roamProfile.negotiatedUCEncryptionType);
3174
3175 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3176 &pWextState->roamProfile, true);
3177 setKey.keyLength = 0;
3178 setKey.keyDirection = eSIR_TX_RX;
3179
3180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3181 if (pairwise)
3182 {
3183#endif
3184 if (mac_addr)
3185 {
3186 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3187 }
3188 else
3189 {
3190 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3191 * and peerMacAddress in case of IBSS*/
3192 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3193 {
3194 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3195 if (HDD_MAX_NUM_IBSS_STA != staidx)
3196 {
3197 vos_mem_copy(setKey.peerMac,
3198 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3199 WNI_CFG_BSSID_LEN);
3200
3201 }
3202 else
3203 {
3204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3205 __func__);
3206 return -EOPNOTSUPP;
3207 }
3208 }
3209 else
3210 {
3211 vos_mem_copy(setKey.peerMac,
3212 &pHddStaCtx->conn_info.bssId[0],
3213 WNI_CFG_BSSID_LEN);
3214 }
3215 }
3216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3217 }
3218 else
3219 {
3220 /* set group key*/
3221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3222 "%s- %d: setting Group key",
3223 __func__, __LINE__);
3224 setKey.keyDirection = eSIR_RX_ONLY;
3225 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3226 }
3227#endif
3228 }
3229 else if (
3230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3231 (!pairwise)
3232#else
3233 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3234#endif
3235 )
3236 {
3237 /* set group key*/
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3239 "%s- %d: setting Group key",
3240 __func__, __LINE__);
3241 setKey.keyDirection = eSIR_RX_ONLY;
3242 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3243 }
3244 else
3245 {
3246 /* set pairwise key*/
3247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3248 "%s- %d: setting pairwise key",
3249 __func__, __LINE__);
3250 setKey.keyDirection = eSIR_TX_RX;
3251 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3252 }
3253
3254 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3255 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3256 __func__, setKey.peerMac[0], setKey.peerMac[1],
3257 setKey.peerMac[2], setKey.peerMac[3],
3258 setKey.peerMac[4], setKey.peerMac[5],
3259 setKey.keyDirection);
3260
3261 vos_status = wlan_hdd_check_ula_done(pAdapter);
3262
3263 if ( vos_status != VOS_STATUS_SUCCESS )
3264 {
3265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3266 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3267 __LINE__, vos_status );
3268
3269 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3270
3271 return -EINVAL;
3272
3273 }
3274
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003275#ifdef WLAN_FEATURE_VOWIFI_11R
3276 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3277 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003278 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303279 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003280 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303281 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003282 }
3283#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003284
3285 /* issue set key request to SME*/
3286 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3287 pAdapter->sessionId, &setKey, &roamId );
3288
3289 if ( 0 != status )
3290 {
3291 hddLog(VOS_TRACE_LEVEL_ERROR,
3292 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3293 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3294 return -EINVAL;
3295 }
3296
3297
3298 /* in case of IBSS as there was no information available about WEP keys during
3299 * IBSS join, group key intialized with NULL key, so re-initialize group key
3300 * with correct value*/
3301 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3302 !( ( IW_AUTH_KEY_MGMT_802_1X
3303 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3304 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3305 )
3306 &&
3307 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3308 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3309 )
3310 )
3311 {
3312 setKey.keyDirection = eSIR_RX_ONLY;
3313 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3314
3315 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3316 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3317 __func__, setKey.peerMac[0], setKey.peerMac[1],
3318 setKey.peerMac[2], setKey.peerMac[3],
3319 setKey.peerMac[4], setKey.peerMac[5],
3320 setKey.keyDirection);
3321
3322 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3323 pAdapter->sessionId, &setKey, &roamId );
3324
3325 if ( 0 != status )
3326 {
3327 hddLog(VOS_TRACE_LEVEL_ERROR,
3328 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3329 __func__, status);
3330 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3331 return -EINVAL;
3332 }
3333 }
3334 }
3335
3336 return 0;
3337}
3338
3339/*
3340 * FUNCTION: wlan_hdd_cfg80211_get_key
3341 * This function is used to get the key information
3342 */
3343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3344static int wlan_hdd_cfg80211_get_key(
3345 struct wiphy *wiphy,
3346 struct net_device *ndev,
3347 u8 key_index, bool pairwise,
3348 const u8 *mac_addr, void *cookie,
3349 void (*callback)(void *cookie, struct key_params*)
3350 )
3351#else
3352static int wlan_hdd_cfg80211_get_key(
3353 struct wiphy *wiphy,
3354 struct net_device *ndev,
3355 u8 key_index, const u8 *mac_addr, void *cookie,
3356 void (*callback)(void *cookie, struct key_params*)
3357 )
3358#endif
3359{
3360 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3361 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3362 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3363 struct key_params params;
3364
3365 ENTER();
3366
3367 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3368 __func__,pAdapter->device_mode);
3369
3370 memset(&params, 0, sizeof(params));
3371
3372 if (CSR_MAX_NUM_KEY <= key_index)
3373 {
3374 return -EINVAL;
3375 }
3376
3377 switch(pRoamProfile->EncryptionType.encryptionType[0])
3378 {
3379 case eCSR_ENCRYPT_TYPE_NONE:
3380 params.cipher = IW_AUTH_CIPHER_NONE;
3381 break;
3382
3383 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3384 case eCSR_ENCRYPT_TYPE_WEP40:
3385 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3386 break;
3387
3388 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3389 case eCSR_ENCRYPT_TYPE_WEP104:
3390 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3391 break;
3392
3393 case eCSR_ENCRYPT_TYPE_TKIP:
3394 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3395 break;
3396
3397 case eCSR_ENCRYPT_TYPE_AES:
3398 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3399 break;
3400
3401 default:
3402 params.cipher = IW_AUTH_CIPHER_NONE;
3403 break;
3404 }
3405
3406 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3407 params.seq_len = 0;
3408 params.seq = NULL;
3409 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3410 callback(cookie, &params);
3411 return 0;
3412}
3413
3414/*
3415 * FUNCTION: wlan_hdd_cfg80211_del_key
3416 * This function is used to delete the key information
3417 */
3418#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3419static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3420 struct net_device *ndev,
3421 u8 key_index,
3422 bool pairwise,
3423 const u8 *mac_addr
3424 )
3425#else
3426static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3427 struct net_device *ndev,
3428 u8 key_index,
3429 const u8 *mac_addr
3430 )
3431#endif
3432{
3433 int status = 0;
3434
3435 //This code needs to be revisited. There is sme_removeKey API, we should
3436 //plan to use that. After the change to use correct index in setkey,
3437 //it is observed that this is invalidating peer
3438 //key index whenever re-key is done. This is affecting data link.
3439 //It should be ok to ignore del_key.
3440#if 0
3441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3442 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3443 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3444 tCsrRoamSetKey setKey;
3445 v_U32_t roamId= 0xFF;
3446
3447 ENTER();
3448
3449 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3450 __func__,pAdapter->device_mode);
3451
3452 if (CSR_MAX_NUM_KEY <= key_index)
3453 {
3454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3455 key_index);
3456
3457 return -EINVAL;
3458 }
3459
3460 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3461 setKey.keyId = key_index;
3462
3463 if (mac_addr)
3464 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3465 else
3466 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3467
3468 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3469
3470 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003472 )
3473 {
3474
3475 hdd_hostapd_state_t *pHostapdState =
3476 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3477 if( pHostapdState->bssState == BSS_START)
3478 {
3479 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3480
3481 if ( status != eHAL_STATUS_SUCCESS )
3482 {
3483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3484 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3485 __LINE__, status );
3486 }
3487 }
3488 }
3489 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003490 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003491 )
3492 {
3493 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3494
3495 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3496
3497 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3498 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3499 __func__, setKey.peerMac[0], setKey.peerMac[1],
3500 setKey.peerMac[2], setKey.peerMac[3],
3501 setKey.peerMac[4], setKey.peerMac[5]);
3502 if(pAdapter->sessionCtx.station.conn_info.connState ==
3503 eConnectionState_Associated)
3504 {
3505 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3506 pAdapter->sessionId, &setKey, &roamId );
3507
3508 if ( 0 != status )
3509 {
3510 hddLog(VOS_TRACE_LEVEL_ERROR,
3511 "%s: sme_RoamSetKey failure, returned %d",
3512 __func__, status);
3513 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3514 return -EINVAL;
3515 }
3516 }
3517 }
3518#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003519 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003520 return status;
3521}
3522
3523/*
3524 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3525 * This function is used to set the default tx key index
3526 */
3527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3528static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3529 struct net_device *ndev,
3530 u8 key_index,
3531 bool unicast, bool multicast)
3532#else
3533static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3534 struct net_device *ndev,
3535 u8 key_index)
3536#endif
3537{
3538 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3539 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3540 int status = 0;
3541 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3542
3543 ENTER();
3544
3545 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3546 __func__,pAdapter->device_mode, key_index);
3547
3548 if (CSR_MAX_NUM_KEY <= key_index)
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3551 key_index);
3552
3553 return -EINVAL;
3554 }
3555
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003556 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3557 {
3558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3559 "%s:LOGP in Progress. Ignore!!!", __func__);
3560 return -EAGAIN;
3561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003562
3563 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003564 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003565 )
3566 {
3567 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3568 (eCSR_ENCRYPT_TYPE_TKIP !=
3569 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3570 (eCSR_ENCRYPT_TYPE_AES !=
3571 pWextState->roamProfile.EncryptionType.encryptionType[0])
3572 )
3573 {
3574 /* if default key index is not same as previous one,
3575 * then update the default key index */
3576
3577 tCsrRoamSetKey setKey;
3578 v_U32_t roamId= 0xFF;
3579 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3580
3581 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3582 __func__, key_index);
3583
3584 Keys->defaultIndex = (u8)key_index;
3585 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3586 setKey.keyId = key_index;
3587 setKey.keyLength = Keys->KeyLength[key_index];
3588
3589 vos_mem_copy(&setKey.Key[0],
3590 &Keys->KeyMaterial[key_index][0],
3591 Keys->KeyLength[key_index]);
3592
3593 setKey.keyDirection = eSIR_TX_ONLY;
3594
3595 vos_mem_copy(setKey.peerMac,
3596 &pHddStaCtx->conn_info.bssId[0],
3597 WNI_CFG_BSSID_LEN);
3598
3599 setKey.encType =
3600 pWextState->roamProfile.EncryptionType.encryptionType[0];
3601
3602 /* issue set key request */
3603 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3604 pAdapter->sessionId, &setKey, &roamId );
3605
3606 if ( 0 != status )
3607 {
3608 hddLog(VOS_TRACE_LEVEL_ERROR,
3609 "%s: sme_RoamSetKey failed, returned %d", __func__,
3610 status);
3611 return -EINVAL;
3612 }
3613 }
3614 }
3615
3616 /* In SoftAp mode setting key direction for default mode */
3617 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3618 {
3619 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3620 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3621 (eCSR_ENCRYPT_TYPE_AES !=
3622 pWextState->roamProfile.EncryptionType.encryptionType[0])
3623 )
3624 {
3625 /* Saving key direction for default key index to TX default */
3626 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3627 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3628 }
3629 }
3630
3631 return status;
3632}
3633
Jeff Johnson295189b2012-06-20 16:38:30 -07003634/*
3635 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3636 * This function is used to inform the BSS details to nl80211 interface.
3637 */
3638static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3639 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3640{
3641 struct net_device *dev = pAdapter->dev;
3642 struct wireless_dev *wdev = dev->ieee80211_ptr;
3643 struct wiphy *wiphy = wdev->wiphy;
3644 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3645 int chan_no;
3646 int ie_length;
3647 const char *ie;
3648 unsigned int freq;
3649 struct ieee80211_channel *chan;
3650 int rssi = 0;
3651 struct cfg80211_bss *bss = NULL;
3652
3653 ENTER();
3654
3655 if( NULL == pBssDesc )
3656 {
3657 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3658 return bss;
3659 }
3660
3661 chan_no = pBssDesc->channelId;
3662 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3663 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3664
3665 if( NULL == ie )
3666 {
3667 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3668 return bss;
3669 }
3670
3671#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3672 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3673 {
3674 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3675 }
3676 else
3677 {
3678 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3679 }
3680#else
3681 freq = ieee80211_channel_to_frequency(chan_no);
3682#endif
3683
3684 chan = __ieee80211_get_channel(wiphy, freq);
3685
3686 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3687 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3688 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3689 if (bss == NULL)
3690 {
3691 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3692
3693 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3694 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3695 pBssDesc->capabilityInfo,
3696 pBssDesc->beaconInterval, ie, ie_length,
3697 rssi, GFP_KERNEL ));
3698}
3699 else
3700 {
3701 return bss;
3702 }
3703}
3704
3705
3706
3707/*
3708 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3709 * This function is used to inform the BSS details to nl80211 interface.
3710 */
3711struct cfg80211_bss*
3712wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3713 tSirBssDescription *bss_desc
3714 )
3715{
3716 /*
3717 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3718 already exists in bss data base of cfg80211 for that particular BSS ID.
3719 Using cfg80211_inform_bss_frame to update the bss entry instead of
3720 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3721 now there is no possibility to get the mgmt(probe response) frame from PE,
3722 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3723 cfg80211_inform_bss_frame.
3724 */
3725 struct net_device *dev = pAdapter->dev;
3726 struct wireless_dev *wdev = dev->ieee80211_ptr;
3727 struct wiphy *wiphy = wdev->wiphy;
3728 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003729#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3730 qcom_ie_age *qie_age = NULL;
3731 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3732#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003733 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 const char *ie =
3736 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3737 unsigned int freq;
3738 struct ieee80211_channel *chan;
3739 struct ieee80211_mgmt *mgmt =
3740 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3741 struct cfg80211_bss *bss_status = NULL;
3742 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3743 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003744#ifdef WLAN_OPEN_SOURCE
3745 struct timespec ts;
3746#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003747
3748 ENTER();
3749
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003750 if (!mgmt)
3751 return NULL;
3752
Jeff Johnson295189b2012-06-20 16:38:30 -07003753 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003754
3755#ifdef WLAN_OPEN_SOURCE
3756 /* Android does not want the timestamp from the frame.
3757 Instead it wants a monotonic increasing value */
3758 get_monotonic_boottime(&ts);
3759 mgmt->u.probe_resp.timestamp =
3760 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3761#else
3762 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003763 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3764 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003765
3766#endif
3767
Jeff Johnson295189b2012-06-20 16:38:30 -07003768 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3769 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003770
3771#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3772 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3773 /* Assuming this is the last IE, copy at the end */
3774 ie_length -=sizeof(qcom_ie_age);
3775 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3776 qie_age->element_id = QCOM_VENDOR_IE_ID;
3777 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3778 qie_age->oui_1 = QCOM_OUI1;
3779 qie_age->oui_2 = QCOM_OUI2;
3780 qie_age->oui_3 = QCOM_OUI3;
3781 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3782 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3783#endif
3784
Jeff Johnson295189b2012-06-20 16:38:30 -07003785 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3786
3787 mgmt->frame_control |=
3788 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3789
3790#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3791 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3792 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3793 {
3794 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3795 }
3796 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3797 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3798
3799 {
3800 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3801 }
3802 else
3803 {
3804 kfree(mgmt);
3805 return NULL;
3806 }
3807#else
3808 freq = ieee80211_channel_to_frequency(chan_no);
3809#endif
3810 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003811 /*when the band is changed on the fly using the GUI, three things are done
3812 * 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)
3813 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3814 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3815 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3816 * and discards the channels correponding to previous band and calls back with zero bss results.
3817 * 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
3818 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3819 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3820 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3821 * So drop the bss and continue to next bss.
3822 */
3823 if(chan == NULL)
3824 {
3825 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3826 return NULL;
3827 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003828 /*To keep the rssi icon of the connected AP in the scan window
3829 *and the rssi icon of the wireless networks in sync
3830 * */
3831 if (( eConnectionState_Associated ==
3832 pAdapter->sessionCtx.station.conn_info.connState ) &&
3833 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3834 pAdapter->sessionCtx.station.conn_info.bssId,
3835 WNI_CFG_BSSID_LEN)))
3836 {
3837 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3838 rssi = (pAdapter->rssi * 100);
3839 }
3840 else
3841 {
3842 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3843 }
3844
3845 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3846 frame_len, rssi, GFP_KERNEL);
3847 kfree(mgmt);
3848 return bss_status;
3849}
3850
3851/*
3852 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3853 * This function is used to update the BSS data base of CFG8011
3854 */
3855struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3856 tCsrRoamInfo *pRoamInfo
3857 )
3858{
3859 tCsrRoamConnectedProfile roamProfile;
3860 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3861 struct cfg80211_bss *bss = NULL;
3862
3863 ENTER();
3864
3865 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3866 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3867
3868 if (NULL != roamProfile.pBssDesc)
3869 {
3870 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3871 &roamProfile);
3872
3873 if (NULL == bss)
3874 {
3875 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3876 __func__);
3877 }
3878
3879 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3880 }
3881 else
3882 {
3883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3884 __func__);
3885 }
3886 return bss;
3887}
3888
3889/*
3890 * FUNCTION: wlan_hdd_cfg80211_update_bss
3891 */
3892static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3893 hdd_adapter_t *pAdapter
3894 )
3895{
3896 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3897 tCsrScanResultInfo *pScanResult;
3898 eHalStatus status = 0;
3899 tScanResultHandle pResult;
3900 struct cfg80211_bss *bss_status = NULL;
3901
3902 ENTER();
3903
3904 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3905 {
3906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3907 return -EAGAIN;
3908 }
3909
3910 /*
3911 * start getting scan results and populate cgf80211 BSS database
3912 */
3913 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3914
3915 /* no scan results */
3916 if (NULL == pResult)
3917 {
3918 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3919 return status;
3920 }
3921
3922 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3923
3924 while (pScanResult)
3925 {
3926 /*
3927 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3928 * entry already exists in bss data base of cfg80211 for that
3929 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3930 * bss entry instead of cfg80211_inform_bss, But this call expects
3931 * mgmt packet as input. As of now there is no possibility to get
3932 * the mgmt(probe response) frame from PE, converting bss_desc to
3933 * ieee80211_mgmt(probe response) and passing to c
3934 * fg80211_inform_bss_frame.
3935 * */
3936
3937 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3938 &pScanResult->BssDescriptor);
3939
3940
3941 if (NULL == bss_status)
3942 {
3943 hddLog(VOS_TRACE_LEVEL_INFO,
3944 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3945 }
3946 else
3947 {
3948 cfg80211_put_bss(bss_status);
3949 }
3950
3951 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3952 }
3953
3954 sme_ScanResultPurge(hHal, pResult);
3955
3956 return 0;
3957}
3958
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003959void
3960hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3961{
3962 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003963 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3964 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3965 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003966} /****** end hddPrintMacAddr() ******/
3967
3968void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003969hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003970{
3971 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003972 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3973 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3974 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3975 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003976} /****** end hddPrintPmkId() ******/
3977
3978//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3979//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3980
3981//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3982//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3983
3984#define dump_bssid(bssid) \
3985 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003986 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3987 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3988 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003989 }
3990
3991#define dump_pmkid(pMac, pmkid) \
3992 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003993 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3994 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3995 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003996 }
3997
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003998#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003999/*
4000 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4001 * This function is used to notify the supplicant of a new PMKSA candidate.
4002 */
4003int wlan_hdd_cfg80211_pmksa_candidate_notify(
4004 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
4005 int index, bool preauth )
4006{
Jeff Johnsone7245742012-09-05 17:12:55 -07004007#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004008 struct net_device *dev = pAdapter->dev;
4009
4010 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004011 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004012
4013 if( NULL == pRoamInfo )
4014 {
4015 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4016 return -EINVAL;
4017 }
4018
4019 dump_bssid(pRoamInfo->bssid);
4020 cfg80211_pmksa_candidate_notify(dev, index,
4021 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07004022#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004023 return 0;
4024}
4025#endif //FEATURE_WLAN_LFR
4026
Jeff Johnson295189b2012-06-20 16:38:30 -07004027/*
4028 * FUNCTION: hdd_cfg80211_scan_done_callback
4029 * scanning callback function, called after finishing scan
4030 *
4031 */
4032static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
4033 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4034{
4035 struct net_device *dev = (struct net_device *) pContext;
4036 //struct wireless_dev *wdev = dev->ieee80211_ptr;
4037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004038 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4039 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004040 struct cfg80211_scan_request *req = NULL;
4041 int ret = 0;
4042
4043 ENTER();
4044
4045 hddLog(VOS_TRACE_LEVEL_INFO,
4046 "%s called with halHandle = %p, pContext = %p,"
4047 "scanID = %d, returned status = %d\n",
4048 __func__, halHandle, pContext, (int) scanId, (int) status);
4049
4050 //Block on scan req completion variable. Can't wait forever though.
4051 ret = wait_for_completion_interruptible_timeout(
4052 &pScanInfo->scan_req_completion_event,
4053 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4054 if (!ret)
4055 {
4056 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004057 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004058 }
4059
4060 if(pScanInfo->mScanPending != VOS_TRUE)
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 /* Check the scanId */
4067 if (pScanInfo->scanId != scanId)
4068 {
4069 hddLog(VOS_TRACE_LEVEL_INFO,
4070 "%s called with mismatched scanId pScanInfo->scanId = %d "
4071 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
4072 (int) scanId);
4073 }
4074
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
4076 pAdapter);
4077
4078 if (0 > ret)
4079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
4080
4081
4082 /* If any client wait scan result through WEXT
4083 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004084 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 {
4086 /* The other scan request waiting for current scan finish
4087 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004088 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004090 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004091 }
4092 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004093 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004094 {
4095 struct net_device *dev = pAdapter->dev;
4096 union iwreq_data wrqu;
4097 int we_event;
4098 char *msg;
4099
4100 memset(&wrqu, '\0', sizeof(wrqu));
4101 we_event = SIOCGIWSCAN;
4102 msg = NULL;
4103 wireless_send_event(dev, we_event, &wrqu, msg);
4104 }
4105 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004106 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004107
4108 /* Get the Scan Req */
4109 req = pAdapter->request;
4110
4111 if (!req)
4112 {
4113 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004114 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004115 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004116 }
4117
4118 /*
4119 * setting up 0, just in case.
4120 */
4121 req->n_ssids = 0;
4122 req->n_channels = 0;
4123 req->ie = 0;
4124
Jeff Johnson295189b2012-06-20 16:38:30 -07004125 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004126 /* Scan is no longer pending */
4127 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004128
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004129 /*
4130 * cfg80211_scan_done informing NL80211 about completion
4131 * of scanning
4132 */
4133 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004134 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004135
Jeff Johnsone7245742012-09-05 17:12:55 -07004136allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004137 /* release the wake lock at the end of the scan*/
4138 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004139
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004140 /* Acquire wakelock to handle the case where APP's tries to suspend
4141 * immediatly after the driver gets connect request(i.e after scan)
4142 * from supplicant, this result in app's is suspending and not able
4143 * to process the connect request to AP */
4144 hdd_allow_suspend_timeout(100);
4145
Jeff Johnson295189b2012-06-20 16:38:30 -07004146 EXIT();
4147 return 0;
4148}
4149
4150/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004151 * FUNCTION: hdd_isScanAllowed
4152 * Go through each adapter and check if scan allowed
4153 *
4154 */
4155v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4156{
4157 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4158 hdd_station_ctx_t *pHddStaCtx = NULL;
4159 hdd_adapter_t *pAdapter = NULL;
4160 VOS_STATUS status = 0;
4161 v_U8_t staId = 0;
4162 v_U8_t *staMac = NULL;
4163
4164 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4165
4166 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4167 {
4168 pAdapter = pAdapterNode->pAdapter;
4169
4170 if( pAdapter )
4171 {
4172 hddLog(VOS_TRACE_LEVEL_INFO,
4173 "%s: Adapter with device mode %d exists",
4174 __func__, pAdapter->device_mode);
4175 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4176 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4177 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4178 {
4179 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4180 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4181 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4182 {
4183 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4184 hddLog(VOS_TRACE_LEVEL_ERROR,
4185 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4186 "middle of WPS/EAPOL exchange.", __func__,
4187 staMac[0], staMac[1], staMac[2],
4188 staMac[3], staMac[4], staMac[5]);
4189 return VOS_FALSE;
4190 }
4191 }
4192 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4193 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4194 {
4195 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4196 {
4197 if ((pAdapter->aStaInfo[staId].isUsed) &&
4198 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4199 {
4200 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4201
4202 hddLog(VOS_TRACE_LEVEL_ERROR,
4203 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4204 "middle of WPS/EAPOL exchange.", __func__,
4205 staMac[0], staMac[1], staMac[2],
4206 staMac[3], staMac[4], staMac[5]);
4207 return VOS_FALSE;
4208 }
4209 }
4210 }
4211 }
4212 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4213 pAdapterNode = pNext;
4214 }
4215 hddLog(VOS_TRACE_LEVEL_INFO,
4216 "%s: Scan allowed", __func__);
4217 return VOS_TRUE;
4218}
4219
4220/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004221 * FUNCTION: wlan_hdd_cfg80211_scan
4222 * this scan respond to scan trigger and update cfg80211 scan database
4223 * later, scan dump command can be used to recieve scan results
4224 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004225int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4226#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4227 struct net_device *dev,
4228#endif
4229 struct cfg80211_scan_request *request)
4230{
4231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4232 struct net_device *dev = request->wdev->netdev;
4233#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4235 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4236 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4237 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4238 tCsrScanRequest scanRequest;
4239 tANI_U8 *channelList = NULL, i;
4240 v_U32_t scanId = 0;
4241 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004242 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004243 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004244
4245 ENTER();
4246
4247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4248 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004249
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004250 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004251 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004252 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004253 {
4254 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004255 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4256 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004257 return -EBUSY;
4258 }
4259
Jeff Johnson295189b2012-06-20 16:38:30 -07004260#ifdef WLAN_BTAMP_FEATURE
4261 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004262 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004264 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 "%s: No scanning when AMP is on", __func__);
4266 return -EOPNOTSUPP;
4267 }
4268#endif
4269 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004270 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004272 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004273 "%s: Not scanning on device_mode = %d",
4274 __func__, pAdapter->device_mode);
4275 return -EOPNOTSUPP;
4276 }
4277
4278 if (TRUE == pScanInfo->mScanPending)
4279 {
4280 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004281 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004282 }
4283
4284 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4285 {
4286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4287 "%s:LOGP in Progress. Ignore!!!", __func__);
4288 return -EAGAIN;
4289 }
4290
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004291 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4292 {
4293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4294 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4295 return -EAGAIN;
4296 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004297 //Don't Allow Scan and return busy if Remain On
4298 //Channel and action frame is pending
4299 //Otherwise Cancel Remain On Channel and allow Scan
4300 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004301 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004302 {
4303 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4304 return -EBUSY;
4305 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004306#ifdef FEATURE_WLAN_TDLS
4307 if (wlan_hdd_tdlsConnectedPeers(pAdapter))
4308 {
4309 tANI_U8 staIdx;
4310
4311 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
4312 {
4313 if (pHddCtx->tdlsConnInfo[staIdx].staId)
4314 {
4315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4316 ("scan: indicate TDLS teadown (staId %d)"), pHddCtx->tdlsConnInfo[staIdx].staId) ;
4317
4318#ifdef CONFIG_TDLS_IMPLICIT
4319 cfg80211_tdls_oper_request(pAdapter->dev,
4320 pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes,
4321 NL80211_TDLS_TEARDOWN,
4322 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
4323 GFP_KERNEL);
4324#endif
4325 }
4326 }
4327 return -EBUSY;
4328 }
4329#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004330
Jeff Johnson295189b2012-06-20 16:38:30 -07004331 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4332 {
4333 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004334 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004335 return -EAGAIN;
4336 }
4337 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4338 {
4339 hddLog(VOS_TRACE_LEVEL_WARN,
4340 "%s: MAX TM Level Scan not allowed", __func__);
4341 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4342 return -EBUSY;
4343 }
4344 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4345
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004346 /* Check if scan is allowed at this point of time.
4347 */
4348 if (!hdd_isScanAllowed(pHddCtx))
4349 {
4350 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4351 return -EBUSY;
4352 }
4353
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4355
4356 if (NULL != request)
4357 {
4358 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4359 (int)request->n_ssids);
4360
4361 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4362 * Becasue of this, driver is assuming that this is not wildcard scan and so
4363 * is not aging out the scan results.
4364 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004365 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004366 {
4367 request->n_ssids = 0;
4368 }
4369
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004370 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004371 {
4372 tCsrSSIDInfo *SsidInfo;
4373 int j;
4374 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4375 /* Allocate num_ssid tCsrSSIDInfo structure */
4376 SsidInfo = scanRequest.SSIDs.SSIDList =
4377 ( tCsrSSIDInfo *)vos_mem_malloc(
4378 request->n_ssids*sizeof(tCsrSSIDInfo));
4379
4380 if(NULL == scanRequest.SSIDs.SSIDList)
4381 {
4382 hddLog(VOS_TRACE_LEVEL_ERROR,
4383 "memory alloc failed SSIDInfo buffer");
4384 return -ENOMEM;
4385 }
4386
4387 /* copy all the ssid's and their length */
4388 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4389 {
4390 /* get the ssid length */
4391 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4392 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4393 SsidInfo->SSID.length);
4394 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4395 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4396 j, SsidInfo->SSID.ssId);
4397 }
4398 /* set the scan type to active */
4399 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4400 }
4401 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4402 {
4403 /* set the scan type to active */
4404 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4405 }
4406 else
4407 {
4408 /*Set the scan type to default type, in this case it is ACTIVE*/
4409 scanRequest.scanType = pScanInfo->scan_mode;
4410 }
4411 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4412 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4413 }
4414 else
4415 {
4416 /* set the scan type to active */
4417 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4418 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4419
4420 /* set min and max channel time to zero */
4421 scanRequest.minChnTime = 0;
4422 scanRequest.maxChnTime = 0;
4423 }
4424
4425 /* set BSSType to default type */
4426 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4427
4428 /*TODO: scan the requested channels only*/
4429
4430 /*Right now scanning all the channels */
4431 if( request )
4432 {
4433 if( request->n_channels )
4434 {
4435 channelList = vos_mem_malloc( request->n_channels );
4436 if( NULL == channelList )
4437 {
4438 status = -ENOMEM;
4439 goto free_mem;
4440 }
4441
4442 for( i = 0 ; i < request->n_channels ; i++ )
4443 channelList[i] = request->channels[i]->hw_value;
4444 }
4445
4446 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4447 scanRequest.ChannelInfo.ChannelList = channelList;
4448
4449 /* set requestType to full scan */
4450 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004451
4452 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4453 * search (Flush on both full scan and social scan but not on single
4454 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4455 */
4456
4457 /* Supplicant does single channel scan after 8-way handshake
4458 * and in that case driver shoudnt flush scan results. If
4459 * driver flushes the scan results here and unfortunately if
4460 * the AP doesnt respond to our probe req then association
4461 * fails which is not desired
4462 */
4463
4464 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4465 {
4466 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4467 pAdapter->sessionId );
4468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004469
4470 if( request->ie_len )
4471 {
4472 /* save this for future association (join requires this) */
4473 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4474 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4475 pScanInfo->scanAddIE.length = request->ie_len;
4476
4477 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004478 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4479 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 )
4481 {
4482 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4483 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4484 }
4485
4486 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4487 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4488
Jeff Johnson295189b2012-06-20 16:38:30 -07004489 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4490 request->ie_len);
4491 if (pP2pIe != NULL)
4492 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004493#ifdef WLAN_FEATURE_P2P_DEBUG
4494 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4495 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4496 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4497 {
4498 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4499 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4500 "Go nego completed to Connection is started");
4501 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4502 "for 8way Handshake");
4503 }
4504 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4505 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4506 {
4507 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4508 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4509 "Disconnected state to Connection is started");
4510 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4511 "for 4way Handshake");
4512 }
4513#endif
4514
Jeff Johnsone7245742012-09-05 17:12:55 -07004515 /* no_cck will be set during p2p find to disable 11b rates */
4516 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004517 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004518 hddLog(VOS_TRACE_LEVEL_INFO,
4519 "%s: This is a P2P Search", __func__);
4520 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004521
Jeff Johnsone7245742012-09-05 17:12:55 -07004522 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4523 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004524 /* set requestType to P2P Discovery */
4525 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004526 }
4527
4528 /*
4529 Skip Dfs Channel in case of P2P Search
4530 if it is set in ini file
4531 */
4532 if(cfg_param->skipDfsChnlInP2pSearch)
4533 {
4534 scanRequest.skipDfsChnlInP2pSearch = 1;
4535 }
4536 else
4537 {
4538 scanRequest.skipDfsChnlInP2pSearch = 0;
4539 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004540
Jeff Johnson295189b2012-06-20 16:38:30 -07004541 }
4542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004543 }
4544 }
4545
4546 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4547
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004548 /* acquire the wakelock to avoid the apps suspend during the scan. To
4549 * address the following issues.
4550 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4551 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4552 * for long time, this result in apps running at full power for long time.
4553 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4554 * be stuck in full power because of resume BMPS
4555 */
4556 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004557
4558 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004559 pAdapter->sessionId, &scanRequest, &scanId,
4560 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004561
Jeff Johnson295189b2012-06-20 16:38:30 -07004562 if (eHAL_STATUS_SUCCESS != status)
4563 {
4564 hddLog(VOS_TRACE_LEVEL_ERROR,
4565 "%s: sme_ScanRequest returned error %d", __func__, status);
4566 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004567 if(eHAL_STATUS_RESOURCES == status)
4568 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004569 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 -07004570 status = -EBUSY;
4571 } else {
4572 status = -EIO;
4573 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004574 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004575 goto free_mem;
4576 }
4577
4578 pScanInfo->mScanPending = TRUE;
4579 pAdapter->request = request;
4580 pScanInfo->scanId = scanId;
4581
4582 complete(&pScanInfo->scan_req_completion_event);
4583
4584free_mem:
4585 if( scanRequest.SSIDs.SSIDList )
4586 {
4587 vos_mem_free(scanRequest.SSIDs.SSIDList);
4588 }
4589
4590 if( channelList )
4591 vos_mem_free( channelList );
4592
4593 EXIT();
4594
4595 return status;
4596}
4597
4598/*
4599 * FUNCTION: wlan_hdd_cfg80211_connect_start
4600 * This function is used to start the association process
4601 */
4602int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004603 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004604{
4605 int status = 0;
4606 hdd_wext_state_t *pWextState;
4607 v_U32_t roamId;
4608 tCsrRoamProfile *pRoamProfile;
4609 eMib_dot11DesiredBssType connectedBssType;
4610 eCsrAuthType RSNAuthType;
4611
4612 ENTER();
4613
4614 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4615
4616 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4617 {
4618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4619 return -EINVAL;
4620 }
4621
4622 pRoamProfile = &pWextState->roamProfile;
4623
4624 if (pRoamProfile)
4625 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004626 int ret = 0;
4627 hdd_station_ctx_t *pHddStaCtx;
4628 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4629 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4630
4631 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4632 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4633 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004634 {
4635 /* Issue disconnect to CSR */
4636 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4637 if( eHAL_STATUS_SUCCESS ==
4638 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4639 pAdapter->sessionId,
4640 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4641 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004642 ret = wait_for_completion_interruptible_timeout(
4643 &pAdapter->disconnect_comp_var,
4644 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4645 if (0 == ret)
4646 {
4647 VOS_ASSERT(0);
4648 }
4649 }
4650 }
4651 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4652 {
4653 ret = wait_for_completion_interruptible_timeout(
4654 &pAdapter->disconnect_comp_var,
4655 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4656 if (0 == ret)
4657 {
4658 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004659 }
4660 }
4661
4662 if (HDD_WMM_USER_MODE_NO_QOS ==
4663 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4664 {
4665 /*QoS not enabled in cfg file*/
4666 pRoamProfile->uapsd_mask = 0;
4667 }
4668 else
4669 {
4670 /*QoS enabled, update uapsd mask from cfg file*/
4671 pRoamProfile->uapsd_mask =
4672 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4673 }
4674
4675 pRoamProfile->SSIDs.numOfSSIDs = 1;
4676 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4677 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4678 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4679 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4680 ssid, ssid_len);
4681
4682 if (bssid)
4683 {
4684 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4685 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4686 WNI_CFG_BSSID_LEN);
4687 /* Save BSSID in seperate variable as well, as RoamProfile
4688 BSSID is getting zeroed out in the association process. And in
4689 case of join failure we should send valid BSSID to supplicant
4690 */
4691 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4692 WNI_CFG_BSSID_LEN);
4693 }
4694
4695 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4696 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4697 {
4698 /*set gen ie*/
4699 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4700 /*set auth*/
4701 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4702 }
4703 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4704 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4705 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4706 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4707 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4708 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4709 )
4710 {
4711 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4712 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4713 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4714 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4715 eCSR_AUTH_TYPE_AUTOSWITCH;
4716 pWextState->roamProfile.AuthType.authType[0] =
4717 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4718 }
4719#ifdef FEATURE_WLAN_WAPI
4720 if (pAdapter->wapi_info.nWapiMode)
4721 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004722 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004723 switch (pAdapter->wapi_info.wapiAuthMode)
4724 {
4725 case WAPI_AUTH_MODE_PSK:
4726 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004727 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004728 pAdapter->wapi_info.wapiAuthMode);
4729 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4730 break;
4731 }
4732 case WAPI_AUTH_MODE_CERT:
4733 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004734 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004735 pAdapter->wapi_info.wapiAuthMode);
4736 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4737 break;
4738 }
4739 } // End of switch
4740 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4741 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4742 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004743 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004744 pRoamProfile->AuthType.numEntries = 1;
4745 pRoamProfile->EncryptionType.numEntries = 1;
4746 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4747 pRoamProfile->mcEncryptionType.numEntries = 1;
4748 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4749 }
4750 }
4751#endif /* FEATURE_WLAN_WAPI */
4752 pRoamProfile->csrPersona = pAdapter->device_mode;
4753
Jeff Johnson32d95a32012-09-10 13:15:23 -07004754 if( operatingChannel )
4755 {
4756 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4757 pRoamProfile->ChannelInfo.numOfChannels = 1;
4758 }
4759
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004760 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4761 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4762 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4763 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004764 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4765 */
4766 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4767 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4768 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004769
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4771 pAdapter->sessionId, pRoamProfile, &roamId);
4772
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004773 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304774 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4775
4776 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4778 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4779 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304780 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004781 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304782 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004783
4784 pRoamProfile->ChannelInfo.ChannelList = NULL;
4785 pRoamProfile->ChannelInfo.numOfChannels = 0;
4786
Jeff Johnson295189b2012-06-20 16:38:30 -07004787 }
4788 else
4789 {
4790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4791 return -EINVAL;
4792 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004793 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004794 return status;
4795}
4796
4797/*
4798 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4799 * This function is used to set the authentication type (OPEN/SHARED).
4800 *
4801 */
4802static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4803 enum nl80211_auth_type auth_type)
4804{
4805 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4806 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4807
4808 ENTER();
4809
4810 /*set authentication type*/
4811 switch (auth_type)
4812 {
4813 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4814 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004815#ifdef WLAN_FEATURE_VOWIFI_11R
4816 case NL80211_AUTHTYPE_FT:
4817#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004818 hddLog(VOS_TRACE_LEVEL_INFO,
4819 "%s: set authentication type to OPEN", __func__);
4820 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4821 break;
4822
4823 case NL80211_AUTHTYPE_SHARED_KEY:
4824 hddLog(VOS_TRACE_LEVEL_INFO,
4825 "%s: set authentication type to SHARED", __func__);
4826 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4827 break;
4828#ifdef FEATURE_WLAN_CCX
4829 case NL80211_AUTHTYPE_NETWORK_EAP:
4830 hddLog(VOS_TRACE_LEVEL_INFO,
4831 "%s: set authentication type to CCKM WPA", __func__);
4832 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4833 break;
4834#endif
4835
4836
4837 default:
4838 hddLog(VOS_TRACE_LEVEL_ERROR,
4839 "%s: Unsupported authentication type %d", __func__,
4840 auth_type);
4841 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4842 return -EINVAL;
4843 }
4844
4845 pWextState->roamProfile.AuthType.authType[0] =
4846 pHddStaCtx->conn_info.authType;
4847 return 0;
4848}
4849
4850/*
4851 * FUNCTION: wlan_hdd_set_akm_suite
4852 * This function is used to set the key mgmt type(PSK/8021x).
4853 *
4854 */
4855static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4856 u32 key_mgmt
4857 )
4858{
4859 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4860 ENTER();
4861
4862 /*set key mgmt type*/
4863 switch(key_mgmt)
4864 {
4865 case WLAN_AKM_SUITE_PSK:
4866 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4867 __func__);
4868 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4869 break;
4870
4871 case WLAN_AKM_SUITE_8021X:
4872 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4873 __func__);
4874 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4875 break;
4876#ifdef FEATURE_WLAN_CCX
4877#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4878#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4879 case WLAN_AKM_SUITE_CCKM:
4880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4881 __func__);
4882 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4883 break;
4884#endif
4885
4886 default:
4887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4888 __func__, key_mgmt);
4889 return -EINVAL;
4890
4891 }
4892 return 0;
4893}
4894
4895/*
4896 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4897 * This function is used to set the encryption type
4898 * (NONE/WEP40/WEP104/TKIP/CCMP).
4899 */
4900static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4901 u32 cipher,
4902 bool ucast
4903 )
4904{
4905 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4906 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4907 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4908
4909 ENTER();
4910
4911 if (!cipher)
4912 {
4913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4914 __func__, cipher);
4915 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4916 }
4917 else
4918 {
4919
4920 /*set encryption method*/
4921 switch (cipher)
4922 {
4923 case IW_AUTH_CIPHER_NONE:
4924 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4925 break;
4926
4927 case WLAN_CIPHER_SUITE_WEP40:
4928 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4929 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4930 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4931 else
4932 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4933 break;
4934
4935 case WLAN_CIPHER_SUITE_WEP104:
4936 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4937 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4938 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4939 else
4940 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4941 break;
4942
4943 case WLAN_CIPHER_SUITE_TKIP:
4944 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4945 break;
4946
4947 case WLAN_CIPHER_SUITE_CCMP:
4948 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4949 break;
4950#ifdef FEATURE_WLAN_WAPI
4951 case WLAN_CIPHER_SUITE_SMS4:
4952 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4953 break;
4954#endif
4955
4956#ifdef FEATURE_WLAN_CCX
4957 case WLAN_CIPHER_SUITE_KRK:
4958 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4959 break;
4960#endif
4961 default:
4962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4963 __func__, cipher);
4964 return -EOPNOTSUPP;
4965 }
4966 }
4967
4968 if (ucast)
4969 {
4970 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4971 __func__, encryptionType);
4972 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4973 pWextState->roamProfile.EncryptionType.numEntries = 1;
4974 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4975 encryptionType;
4976 }
4977 else
4978 {
4979 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4980 __func__, encryptionType);
4981 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4982 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4983 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4984 }
4985
4986 return 0;
4987}
4988
4989
4990/*
4991 * FUNCTION: wlan_hdd_cfg80211_set_ie
4992 * This function is used to parse WPA/RSN IE's.
4993 */
4994int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4995 u8 *ie,
4996 size_t ie_len
4997 )
4998{
4999 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5000 u8 *genie = ie;
5001 v_U16_t remLen = ie_len;
5002#ifdef FEATURE_WLAN_WAPI
5003 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5004 u16 *tmp;
5005 v_U16_t akmsuiteCount;
5006 int *akmlist;
5007#endif
5008 ENTER();
5009
5010 /* clear previous assocAddIE */
5011 pWextState->assocAddIE.length = 0;
5012 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5013
5014 while (remLen >= 2)
5015 {
5016 v_U16_t eLen = 0;
5017 v_U8_t elementId;
5018 elementId = *genie++;
5019 eLen = *genie++;
5020 remLen -= 2;
5021
5022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
5023 __func__, elementId, eLen);
5024
5025 switch ( elementId )
5026 {
5027 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005028 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 -07005029 {
5030 hddLog(VOS_TRACE_LEVEL_ERROR,
5031 "%s: Invalid WPA IE", __func__);
5032 return -EINVAL;
5033 }
5034 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
5035 {
5036 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5037 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
5038 __func__, eLen + 2);
5039
5040 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5041 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005042 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5043 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005044 VOS_ASSERT(0);
5045 return -ENOMEM;
5046 }
5047 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5048 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5049 pWextState->assocAddIE.length += eLen + 2;
5050
5051 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5052 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5053 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5054 }
5055 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5056 {
5057 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5058 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5059 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5060 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5061 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5064 P2P_OUI_TYPE_SIZE))
5065 /*Consider P2P IE, only for P2P Client */
5066 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5067 {
5068 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5069 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
5070 __func__, eLen + 2);
5071
5072 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5073 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005074 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5075 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 VOS_ASSERT(0);
5077 return -ENOMEM;
5078 }
5079 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5080 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5081 pWextState->assocAddIE.length += eLen + 2;
5082
5083 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5084 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005086#ifdef WLAN_FEATURE_WFD
5087 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5088 WFD_OUI_TYPE_SIZE))
5089 /*Consider WFD IE, only for P2P Client */
5090 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5091 {
5092 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5093 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
5094 __func__, eLen + 2);
5095
5096 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5097 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005098 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5099 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005100 VOS_ASSERT(0);
5101 return -ENOMEM;
5102 }
5103 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5104 // WPS IE + P2P IE + WFD IE
5105 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5106 pWextState->assocAddIE.length += eLen + 2;
5107
5108 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5109 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5110 }
5111#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005112 /* Appending HS 2.0 Indication Element in Assiciation Request */
5113 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005114 HS20_OUI_TYPE_SIZE)) )
5115 {
5116 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5117 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
5118 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005119
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005120 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5121 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005122 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5123 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005124 VOS_ASSERT(0);
5125 return -ENOMEM;
5126 }
5127 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5128 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005129
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005130 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5131 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5132 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005133
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 break;
5135 case DOT11F_EID_RSN:
5136 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5137 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5138 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5139 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5140 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5141 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005142 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5143 case DOT11F_EID_EXTCAP:
5144 {
5145 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5146 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5147 __func__, eLen + 2);
5148
5149 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5150 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005151 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5152 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005153 VOS_ASSERT(0);
5154 return -ENOMEM;
5155 }
5156 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5157 pWextState->assocAddIE.length += eLen + 2;
5158
5159 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5160 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5161 break;
5162 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005163#ifdef FEATURE_WLAN_WAPI
5164 case WLAN_EID_WAPI:
5165 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5166 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5167 pAdapter->wapi_info.nWapiMode);
5168 tmp = (u16 *)ie;
5169 tmp = tmp + 2; // Skip element Id and Len, Version
5170 akmsuiteCount = WPA_GET_LE16(tmp);
5171 tmp = tmp + 1;
5172 akmlist = (int *)(tmp);
5173 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5174 {
5175 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5176 }
5177 else
5178 {
5179 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5180 VOS_ASSERT(0);
5181 return -EINVAL;
5182 }
5183
5184 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5185 {
5186 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005187 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005188 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5189 }
5190 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5191 {
5192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
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_CERT;
5195 }
5196 break;
5197#endif
5198 default:
5199 hddLog (VOS_TRACE_LEVEL_ERROR,
5200 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005201 /* when Unknown IE is received we should break and continue
5202 * to the next IE in the buffer instead we were returning
5203 * so changing this to break */
5204 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 }
5206 genie += eLen;
5207 remLen -= eLen;
5208 }
5209 EXIT();
5210 return 0;
5211}
5212
5213/*
5214 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5215 * This function is used to initialize the security
5216 * parameters during connect operation.
5217 */
5218int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5219 struct cfg80211_connect_params *req
5220 )
5221{
5222 int status = 0;
5223 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5224 ENTER();
5225
5226 /*set wpa version*/
5227 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5228
5229 if (req->crypto.wpa_versions)
5230 {
5231 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5232 && ( (req->ie_len)
5233 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5234 // Make sure that it is including a WPA IE.
5235 /* Currently NL is putting WPA version 1 even for open,
5236 * since p2p ie is also put in same buffer.
5237 * */
5238 {
5239 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5240 }
5241 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5242 {
5243 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5244 }
5245 }
5246
5247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5248 pWextState->wpaVersion);
5249
5250 /*set authentication type*/
5251 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5252
5253 if (0 > status)
5254 {
5255 hddLog(VOS_TRACE_LEVEL_ERROR,
5256 "%s: failed to set authentication type ", __func__);
5257 return status;
5258 }
5259
5260 /*set key mgmt type*/
5261 if (req->crypto.n_akm_suites)
5262 {
5263 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5264 if (0 > status)
5265 {
5266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5267 __func__);
5268 return status;
5269 }
5270 }
5271
5272 /*set pairwise cipher type*/
5273 if (req->crypto.n_ciphers_pairwise)
5274 {
5275 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5276 req->crypto.ciphers_pairwise[0], true);
5277 if (0 > status)
5278 {
5279 hddLog(VOS_TRACE_LEVEL_ERROR,
5280 "%s: failed to set unicast cipher type", __func__);
5281 return status;
5282 }
5283 }
5284 else
5285 {
5286 /*Reset previous cipher suite to none*/
5287 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5288 if (0 > status)
5289 {
5290 hddLog(VOS_TRACE_LEVEL_ERROR,
5291 "%s: failed to set unicast cipher type", __func__);
5292 return status;
5293 }
5294 }
5295
5296 /*set group cipher type*/
5297 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5298 false);
5299
5300 if (0 > status)
5301 {
5302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5303 __func__);
5304 return status;
5305 }
5306
5307 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5308 if (req->ie_len)
5309 {
5310 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5311 if ( 0 > status)
5312 {
5313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5314 __func__);
5315 return status;
5316 }
5317 }
5318
5319 /*incase of WEP set default key information*/
5320 if (req->key && req->key_len)
5321 {
5322 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5323 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5324 )
5325 {
5326 if ( IW_AUTH_KEY_MGMT_802_1X
5327 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5328 {
5329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5330 __func__);
5331 return -EOPNOTSUPP;
5332 }
5333 else
5334 {
5335 u8 key_len = req->key_len;
5336 u8 key_idx = req->key_idx;
5337
5338 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5339 && (CSR_MAX_NUM_KEY > key_idx)
5340 )
5341 {
5342 hddLog(VOS_TRACE_LEVEL_INFO,
5343 "%s: setting default wep key, key_idx = %hu key_len %hu",
5344 __func__, key_idx, key_len);
5345 vos_mem_copy(
5346 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5347 req->key, key_len);
5348 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5349 (u8)key_len;
5350 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5351 }
5352 }
5353 }
5354 }
5355
5356 return status;
5357}
5358
5359/*
5360 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5361 * This function is used to initialize the security
5362 * parameters during connect operation.
5363 */
5364static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5365 struct net_device *ndev,
5366 struct cfg80211_connect_params *req
5367 )
5368{
5369 int status = 0;
5370 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5371 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5372 hdd_context_t *pHddCtx = NULL;
5373
5374 ENTER();
5375
5376 hddLog(VOS_TRACE_LEVEL_INFO,
5377 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5378
5379 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5380 {
5381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5382 "%s:LOGP in Progress. Ignore!!!", __func__);
5383 return -EAGAIN;
5384 }
5385
5386#ifdef WLAN_BTAMP_FEATURE
5387 //Infra connect not supported when AMP traffic is on.
5388 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5389 {
5390 hddLog(VOS_TRACE_LEVEL_ERROR,
5391 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005392 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 }
5394#endif
5395 /*initialise security parameters*/
5396 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5397
5398 if ( 0 > status)
5399 {
5400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5401 __func__);
5402 return status;
5403 }
5404
5405 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005406 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005407 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5408 (vos_concurrent_sessions_running()))
5409 {
5410 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5411
5412 if (NULL != pVosContext)
5413 {
5414 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5415 if(NULL != pHddCtx)
5416 {
5417 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5418 }
5419 }
5420 }
5421
Mohit Khanna765234a2012-09-11 15:08:35 -07005422 if ( req->channel )
5423 {
5424 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5425 req->ssid_len, req->bssid,
5426 req->channel->hw_value);
5427 }
5428 else
5429 {
5430 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5431 req->ssid_len, req->bssid,
5432 0);
5433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005434
5435 if (0 > status)
5436 {
5437 //ReEnable BMPS if disabled
5438 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5439 (NULL != pHddCtx))
5440 {
5441 //ReEnable Bmps and Imps back
5442 hdd_enable_bmps_imps(pHddCtx);
5443 }
5444
5445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5446 return status;
5447 }
5448 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5449 EXIT();
5450 return status;
5451}
5452
5453
5454/*
5455 * FUNCTION: wlan_hdd_cfg80211_disconnect
5456 * This function is used to issue a disconnect request to SME
5457 */
5458static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5459 struct net_device *dev,
5460 u16 reason
5461 )
5462{
5463 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5464 tCsrRoamProfile *pRoamProfile =
5465 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5466 int status = 0;
5467 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005468#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005469 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005470 tANI_U8 staIdx;
5471#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005472
5473 ENTER();
5474
5475 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5476 __func__,pAdapter->device_mode);
5477
5478 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5479 __func__, reason);
5480
5481 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5482 {
5483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5484 "%s:LOGP in Progress. Ignore!!!",__func__);
5485 return -EAGAIN;
5486 }
5487 if (NULL != pRoamProfile)
5488 {
5489 /*issue disconnect request to SME, if station is in connected state*/
5490 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5491 {
5492 eCsrRoamDisconnectReason reasonCode =
5493 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5494 switch(reason)
5495 {
5496 case WLAN_REASON_MIC_FAILURE:
5497 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5498 break;
5499
5500 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5501 case WLAN_REASON_DISASSOC_AP_BUSY:
5502 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5503 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5504 break;
5505
5506 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5507 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5508 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5509 break;
5510
5511 case WLAN_REASON_DEAUTH_LEAVING:
5512 default:
5513 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5514 break;
5515 }
5516 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5517 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5518 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5519
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005520#ifdef FEATURE_WLAN_TDLS
5521 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005522 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005523 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005524 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5525 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005526 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005527 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005528 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005529 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
5530 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d %02x:%02x:%02x:%02x:%02x:%02x",
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005531 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005532 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005533 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005534 pAdapter->sessionId,
5535 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005536 }
5537 }
5538#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 /*issue disconnect*/
5540 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5541 pAdapter->sessionId, reasonCode);
5542
5543 if ( 0 != status)
5544 {
5545 hddLog(VOS_TRACE_LEVEL_ERROR,
5546 "%s csrRoamDisconnect failure, returned %d \n",
5547 __func__, (int)status );
5548 return -EINVAL;
5549 }
5550
5551 wait_for_completion_interruptible_timeout(
5552 &pAdapter->disconnect_comp_var,
5553 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5554
5555
5556 /*stop tx queues*/
5557 netif_tx_disable(dev);
5558 netif_carrier_off(dev);
5559 }
5560 }
5561 else
5562 {
5563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5564 }
5565
5566 return status;
5567}
5568
5569/*
5570 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5571 * This function is used to initialize the security
5572 * settings in IBSS mode.
5573 */
5574static int wlan_hdd_cfg80211_set_privacy_ibss(
5575 hdd_adapter_t *pAdapter,
5576 struct cfg80211_ibss_params *params
5577 )
5578{
5579 int status = 0;
5580 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5581 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5582 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5583
5584 ENTER();
5585
5586 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5587
5588 if (params->ie_len && ( NULL != params->ie) )
5589 {
5590 if (WLAN_EID_RSN == params->ie[0])
5591 {
5592 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5593 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5594 }
5595 else
5596 {
5597 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5598 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5599 }
5600 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5601
5602 if (0 > status)
5603 {
5604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5605 __func__);
5606 return status;
5607 }
5608 }
5609
5610 pWextState->roamProfile.AuthType.authType[0] =
5611 pHddStaCtx->conn_info.authType =
5612 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5613
5614 if (params->privacy)
5615 {
5616 /* Security enabled IBSS, At this time there is no information available
5617 * about the security paramters, so initialise the encryption type to
5618 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5619 * The correct security parameters will be updated later in
5620 * wlan_hdd_cfg80211_add_key */
5621 /* Hal expects encryption type to be set inorder
5622 *enable privacy bit in beacons */
5623
5624 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5625 }
5626
5627 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5628 pWextState->roamProfile.EncryptionType.numEntries = 1;
5629 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5630
5631 return status;
5632}
5633
5634/*
5635 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5636 * This function is used to create/join an IBSS
5637 */
5638static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5639 struct net_device *dev,
5640 struct cfg80211_ibss_params *params
5641 )
5642{
5643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5644 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5645 tCsrRoamProfile *pRoamProfile;
5646 int status;
5647 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5648
5649 ENTER();
5650
5651 hddLog(VOS_TRACE_LEVEL_INFO,
5652 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5653
5654 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5655 {
5656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5657 "%s:LOGP in Progress. Ignore!!!", __func__);
5658 return -EAGAIN;
5659 }
5660
5661 if (NULL == pWextState)
5662 {
5663 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5664 __func__);
5665 return -EIO;
5666 }
5667
5668 pRoamProfile = &pWextState->roamProfile;
5669
5670 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5671 {
5672 hddLog (VOS_TRACE_LEVEL_ERROR,
5673 "%s Interface type is not set to IBSS \n", __func__);
5674 return -EINVAL;
5675 }
5676
5677 /* Set Channel */
5678 if (NULL != params->channel)
5679 {
5680 u8 channelNum;
5681 if (IEEE80211_BAND_5GHZ == params->channel->band)
5682 {
5683 hddLog(VOS_TRACE_LEVEL_ERROR,
5684 "%s: IBSS join is called with unsupported band %d",
5685 __func__, params->channel->band);
5686 return -EOPNOTSUPP;
5687 }
5688
5689 /* Get channel number */
5690 channelNum =
5691 ieee80211_frequency_to_channel(params->channel->center_freq);
5692
5693 /*TODO: use macro*/
5694 if (14 >= channelNum)
5695 {
5696 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5697 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5698 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5699 int indx;
5700
5701 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5702 validChan, &numChans))
5703 {
5704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5705 __func__);
5706 return -EOPNOTSUPP;
5707 }
5708
5709 for (indx = 0; indx < numChans; indx++)
5710 {
5711 if (channelNum == validChan[indx])
5712 {
5713 break;
5714 }
5715 }
5716 if (indx >= numChans)
5717 {
5718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5719 __func__, channelNum);
5720 return -EINVAL;
5721 }
5722 /* Set the Operational Channel */
5723 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5724 channelNum);
5725 pRoamProfile->ChannelInfo.numOfChannels = 1;
5726 pHddStaCtx->conn_info.operationChannel = channelNum;
5727 pRoamProfile->ChannelInfo.ChannelList =
5728 &pHddStaCtx->conn_info.operationChannel;
5729 }
5730 else
5731 {
5732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5733 __func__, channelNum);
5734 return -EINVAL;
5735 }
5736 }
5737
5738 /* Initialize security parameters */
5739 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5740 if (status < 0)
5741 {
5742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5743 __func__);
5744 return status;
5745 }
5746
5747 /* Issue connect start */
5748 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005749 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005750
5751 if (0 > status)
5752 {
5753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5754 return status;
5755 }
5756
5757 return 0;
5758}
5759
5760/*
5761 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5762 * This function is used to leave an IBSS
5763 */
5764static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5765 struct net_device *dev
5766 )
5767{
5768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5769 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5770 tCsrRoamProfile *pRoamProfile;
5771
5772 ENTER();
5773
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005774 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5775 {
5776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5777 "%s:LOGP in Progress. Ignore!!!", __func__);
5778 return -EAGAIN;
5779 }
5780
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5782 if (NULL == pWextState)
5783 {
5784 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5785 __func__);
5786 return -EIO;
5787 }
5788
5789 pRoamProfile = &pWextState->roamProfile;
5790
5791 /* Issue disconnect only if interface type is set to IBSS */
5792 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5793 {
5794 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5795 __func__);
5796 return -EINVAL;
5797 }
5798
5799 /* Issue Disconnect request */
5800 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5801 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5802 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5803
5804 return 0;
5805}
5806
5807/*
5808 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5809 * This function is used to set the phy parameters
5810 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5811 */
5812static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5813 u32 changed)
5814{
5815 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5816 tHalHandle hHal = pHddCtx->hHal;
5817
5818 ENTER();
5819
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005820 if ( pHddCtx->isLogpInProgress )
5821 {
5822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5823 "%s:LOGP in Progress. Ignore!!!", __func__);
5824 return -EAGAIN;
5825 }
5826
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5828 {
5829 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5830 WNI_CFG_RTS_THRESHOLD_STAMAX :
5831 wiphy->rts_threshold;
5832
5833 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5834 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5835 {
5836 hddLog(VOS_TRACE_LEVEL_ERROR,
5837 "%s: Invalid RTS Threshold value %hu",
5838 __func__, rts_threshold);
5839 return -EINVAL;
5840 }
5841
5842 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5843 rts_threshold, ccmCfgSetCallback,
5844 eANI_BOOLEAN_TRUE))
5845 {
5846 hddLog(VOS_TRACE_LEVEL_ERROR,
5847 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5848 __func__, rts_threshold);
5849 return -EIO;
5850 }
5851
5852 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5853 rts_threshold);
5854 }
5855
5856 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5857 {
5858 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5859 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5860 wiphy->frag_threshold;
5861
5862 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5863 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5864 {
5865 hddLog(VOS_TRACE_LEVEL_ERROR,
5866 "%s: Invalid frag_threshold value %hu", __func__,
5867 frag_threshold);
5868 return -EINVAL;
5869 }
5870
5871 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5872 frag_threshold, ccmCfgSetCallback,
5873 eANI_BOOLEAN_TRUE))
5874 {
5875 hddLog(VOS_TRACE_LEVEL_ERROR,
5876 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5877 __func__, frag_threshold);
5878 return -EIO;
5879 }
5880
5881 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5882 frag_threshold);
5883 }
5884
5885 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5886 || (changed & WIPHY_PARAM_RETRY_LONG))
5887 {
5888 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5889 wiphy->retry_short :
5890 wiphy->retry_long;
5891
5892 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5893 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5894 {
5895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5896 __func__, retry_value);
5897 return -EINVAL;
5898 }
5899
5900 if (changed & WIPHY_PARAM_RETRY_SHORT)
5901 {
5902 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5903 retry_value, ccmCfgSetCallback,
5904 eANI_BOOLEAN_TRUE))
5905 {
5906 hddLog(VOS_TRACE_LEVEL_ERROR,
5907 "%s: ccmCfgSetInt failed for long retry count %hu",
5908 __func__, retry_value);
5909 return -EIO;
5910 }
5911 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5912 __func__, retry_value);
5913 }
5914 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5915 {
5916 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5917 retry_value, ccmCfgSetCallback,
5918 eANI_BOOLEAN_TRUE))
5919 {
5920 hddLog(VOS_TRACE_LEVEL_ERROR,
5921 "%s: ccmCfgSetInt failed for short retry count %hu",
5922 __func__, retry_value);
5923 return -EIO;
5924 }
5925 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5926 __func__, retry_value);
5927 }
5928 }
5929
5930 return 0;
5931}
5932
5933/*
5934 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5935 * This function is used to set the txpower
5936 */
5937static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5938#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5939 enum tx_power_setting type,
5940#else
5941 enum nl80211_tx_power_setting type,
5942#endif
5943 int dbm)
5944{
5945 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5946 tHalHandle hHal = pHddCtx->hHal;
5947 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5948 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5949
5950 ENTER();
5951
5952 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5953 dbm, ccmCfgSetCallback,
5954 eANI_BOOLEAN_TRUE))
5955 {
5956 hddLog(VOS_TRACE_LEVEL_ERROR,
5957 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5958 return -EIO;
5959 }
5960
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005961 if ( pHddCtx->isLogpInProgress )
5962 {
5963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5964 "%s:LOGP in Progress. Ignore!!!", __func__);
5965 return -EAGAIN;
5966 }
5967
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5969 dbm);
5970
5971 switch(type)
5972 {
5973 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5974 /* Fall through */
5975 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5976 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5977 {
5978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5979 __func__);
5980 return -EIO;
5981 }
5982 break;
5983 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5985 __func__);
5986 return -EOPNOTSUPP;
5987 break;
5988 default:
5989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5990 __func__, type);
5991 return -EIO;
5992 }
5993
5994 return 0;
5995}
5996
5997/*
5998 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5999 * This function is used to read the txpower
6000 */
6001static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6002{
6003
6004 hdd_adapter_t *pAdapter;
6005 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6006
Jeff Johnsone7245742012-09-05 17:12:55 -07006007 ENTER();
6008
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 if (NULL == pHddCtx)
6010 {
6011 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6012 *dbm = 0;
6013 return -ENOENT;
6014 }
6015
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006016 if ( pHddCtx->isLogpInProgress )
6017 {
6018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6019 "%s:LOGP in Progress. Ignore!!!", __func__);
6020 return -EAGAIN;
6021 }
6022
Jeff Johnson295189b2012-06-20 16:38:30 -07006023 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6024 if (NULL == pAdapter)
6025 {
6026 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6027 return -ENOENT;
6028 }
6029
6030 wlan_hdd_get_classAstats(pAdapter);
6031 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6032
Jeff Johnsone7245742012-09-05 17:12:55 -07006033 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 return 0;
6035}
6036
6037static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6038 u8* mac, struct station_info *sinfo)
6039{
6040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6041 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6042 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6043 tANI_U8 rate_flags;
6044
6045 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6046 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006047
6048 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6049 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6050 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6051 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6052 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6053 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6054 tANI_U16 maxRate = 0;
6055 tANI_U16 myRate;
6056 tANI_U16 currentRate = 0;
6057 tANI_U8 maxSpeedMCS = 0;
6058 tANI_U8 maxMCSIdx = 0;
6059 tANI_U8 rateFlag = 1;
6060 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006061 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006062
Jeff Johnsone7245742012-09-05 17:12:55 -07006063 ENTER();
6064
Jeff Johnson295189b2012-06-20 16:38:30 -07006065 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6066 (0 == ssidlen))
6067 {
6068 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6069 " Invalid ssidlen, %d", __func__, ssidlen);
6070 /*To keep GUI happy*/
6071 return 0;
6072 }
6073
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006074 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6075 {
6076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6077 "%s:LOGP in Progress. Ignore!!!", __func__);
6078 return -EAGAIN;
6079 }
6080
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6082 sinfo->filled |= STATION_INFO_SIGNAL;
6083
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006084 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6086
6087 //convert to the UI units of 100kbps
6088 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6089
6090#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006091 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 -07006092 sinfo->signal,
6093 pCfg->reportMaxLinkSpeed,
6094 myRate,
6095 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006096 (int) pCfg->linkSpeedRssiMid,
6097 (int) pCfg->linkSpeedRssiLow,
6098 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006099#endif //LINKSPEED_DEBUG_ENABLED
6100
6101 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6102 {
6103 // we do not want to necessarily report the current speed
6104 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6105 {
6106 // report the max possible speed
6107 rssidx = 0;
6108 }
6109 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6110 {
6111 // report the max possible speed with RSSI scaling
6112 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6113 {
6114 // report the max possible speed
6115 rssidx = 0;
6116 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006117 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006118 {
6119 // report middle speed
6120 rssidx = 1;
6121 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006122 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6123 {
6124 // report middle speed
6125 rssidx = 2;
6126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 else
6128 {
6129 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006130 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 }
6132 }
6133 else
6134 {
6135 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6136 hddLog(VOS_TRACE_LEVEL_ERROR,
6137 "%s: Invalid value for reportMaxLinkSpeed: %u",
6138 __func__, pCfg->reportMaxLinkSpeed);
6139 rssidx = 0;
6140 }
6141
6142 maxRate = 0;
6143
6144 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306145 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6146 OperationalRates, &ORLeng))
6147 {
6148 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6149 /*To keep GUI happy*/
6150 return 0;
6151 }
6152
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 for (i = 0; i < ORLeng; i++)
6154 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006155 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 {
6157 /* Validate Rate Set */
6158 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6159 {
6160 currentRate = supported_data_rate[j].supported_rate[rssidx];
6161 break;
6162 }
6163 }
6164 /* Update MAX rate */
6165 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6166 }
6167
6168 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306169 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6170 ExtendedRates, &ERLeng))
6171 {
6172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6173 /*To keep GUI happy*/
6174 return 0;
6175 }
6176
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 for (i = 0; i < ERLeng; i++)
6178 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006179 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 {
6181 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6182 {
6183 currentRate = supported_data_rate[j].supported_rate[rssidx];
6184 break;
6185 }
6186 }
6187 /* Update MAX rate */
6188 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6189 }
6190
6191 /* Get MCS Rate Set -- but only if we are connected at MCS
6192 rates or if we are always reporting max speed or if we have
6193 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006194 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306196 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6197 MCSRates, &MCSLeng))
6198 {
6199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6200 /*To keep GUI happy*/
6201 return 0;
6202 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 rateFlag = 0;
6204 if (rate_flags & eHAL_TX_RATE_HT40)
6205 {
6206 rateFlag |= 1;
6207 }
6208 if (rate_flags & eHAL_TX_RATE_SGI)
6209 {
6210 rateFlag |= 2;
6211 }
6212
6213 for (i = 0; i < MCSLeng; i++)
6214 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006215 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6216 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 {
6218 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6219 {
6220 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6221 break;
6222 }
6223 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006224 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 {
6226 maxRate = currentRate;
6227 maxSpeedMCS = 1;
6228 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6229 }
6230 }
6231 }
6232
6233 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006234 if (((maxRate < myRate) && (0 == rssidx)) ||
6235 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 {
6237 maxRate = myRate;
6238 if (rate_flags & eHAL_TX_RATE_LEGACY)
6239 {
6240 maxSpeedMCS = 0;
6241 }
6242 else
6243 {
6244 maxSpeedMCS = 1;
6245 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6246 }
6247 }
6248
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006249 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 {
6251 sinfo->txrate.legacy = maxRate;
6252#ifdef LINKSPEED_DEBUG_ENABLED
6253 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6254#endif //LINKSPEED_DEBUG_ENABLED
6255 }
6256 else
6257 {
6258 sinfo->txrate.mcs = maxMCSIdx;
6259 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6260 if (rate_flags & eHAL_TX_RATE_SGI)
6261 {
6262 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6263 }
6264 if (rate_flags & eHAL_TX_RATE_HT40)
6265 {
6266 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6267 }
6268#ifdef LINKSPEED_DEBUG_ENABLED
6269 pr_info("Reporting MCS rate %d flags %x\n",
6270 sinfo->txrate.mcs,
6271 sinfo->txrate.flags );
6272#endif //LINKSPEED_DEBUG_ENABLED
6273 }
6274 }
6275 else
6276 {
6277 // report current rate instead of max rate
6278
6279 if (rate_flags & eHAL_TX_RATE_LEGACY)
6280 {
6281 //provide to the UI in units of 100kbps
6282 sinfo->txrate.legacy = myRate;
6283#ifdef LINKSPEED_DEBUG_ENABLED
6284 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6285#endif //LINKSPEED_DEBUG_ENABLED
6286 }
6287 else
6288 {
6289 //must be MCS
6290 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6291 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6292 if (rate_flags & eHAL_TX_RATE_SGI)
6293 {
6294 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6295 }
6296 if (rate_flags & eHAL_TX_RATE_HT40)
6297 {
6298 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6299 }
6300#ifdef LINKSPEED_DEBUG_ENABLED
6301 pr_info("Reporting actual MCS rate %d flags %x\n",
6302 sinfo->txrate.mcs,
6303 sinfo->txrate.flags );
6304#endif //LINKSPEED_DEBUG_ENABLED
6305 }
6306 }
6307 sinfo->filled |= STATION_INFO_TX_BITRATE;
6308
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006309 sinfo->tx_packets =
6310 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6311 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6312 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6313 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6314
6315 sinfo->tx_retries =
6316 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6317 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6318 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6319 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6320
6321 sinfo->tx_failed =
6322 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6323 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6324 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6325 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6326
6327 sinfo->filled |=
6328 STATION_INFO_TX_PACKETS |
6329 STATION_INFO_TX_RETRIES |
6330 STATION_INFO_TX_FAILED;
6331
6332 EXIT();
6333 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006334}
6335
6336static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6337 struct net_device *dev, bool mode, v_SINT_t timeout)
6338{
6339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6340 VOS_STATUS vos_status;
6341
Jeff Johnsone7245742012-09-05 17:12:55 -07006342 ENTER();
6343
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 if (NULL == pAdapter)
6345 {
6346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6347 return -ENODEV;
6348 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006349 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6350 {
6351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6352 "%s:LOGP in Progress. Ignore!!!", __func__);
6353 return -EAGAIN;
6354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006355
6356 /**The get power cmd from the supplicant gets updated by the nl only
6357 *on successful execution of the function call
6358 *we are oppositely mapped w.r.t mode in the driver
6359 **/
6360 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6361
Jeff Johnsone7245742012-09-05 17:12:55 -07006362 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 if (VOS_STATUS_E_FAILURE == vos_status)
6364 {
6365 return -EINVAL;
6366 }
6367 return 0;
6368}
6369
6370
6371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6372static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6373 struct net_device *netdev,
6374 u8 key_index)
6375{
Jeff Johnsone7245742012-09-05 17:12:55 -07006376 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 return 0;
6378}
6379#endif //LINUX_VERSION_CODE
6380
6381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6382static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6383 struct net_device *dev,
6384 struct ieee80211_txq_params *params)
6385{
Jeff Johnsone7245742012-09-05 17:12:55 -07006386 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 return 0;
6388}
6389#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6390static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6391 struct ieee80211_txq_params *params)
6392{
Jeff Johnsone7245742012-09-05 17:12:55 -07006393 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 return 0;
6395}
6396#endif //LINUX_VERSION_CODE
6397
6398static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6399 struct net_device *dev, u8 *mac)
6400{
6401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006402 VOS_STATUS vos_status;
6403 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006404
Jeff Johnsone7245742012-09-05 17:12:55 -07006405 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6407 {
6408 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6409 return -EINVAL;
6410 }
6411
6412 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6413 {
6414 hddLog( LOGE,
6415 "%s: Wlan Load/Unload is in progress", __func__);
6416 return -EBUSY;
6417 }
6418
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006419 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6420 {
6421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6422 "%s:LOGP in Progress. Ignore!!!", __func__);
6423 return -EAGAIN;
6424 }
6425
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 )
6429 {
6430 if( NULL == mac )
6431 {
6432 v_U16_t i;
6433 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6434 {
6435 if(pAdapter->aStaInfo[i].isUsed)
6436 {
6437 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6438 hddLog(VOS_TRACE_LEVEL_INFO,
6439 "%s: Delete STA with MAC::"
6440 "%02x:%02x:%02x:%02x:%02x:%02x",
6441 __func__,
6442 macAddr[0], macAddr[1], macAddr[2],
6443 macAddr[3], macAddr[4], macAddr[5]);
6444 hdd_softap_sta_deauth(pAdapter, macAddr);
6445 }
6446 }
6447 }
6448 else
6449 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006450
6451 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6452 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6453 {
6454 hddLog(VOS_TRACE_LEVEL_INFO,
6455 "%s: Skip this DEL STA as this is not used::"
6456 "%02x:%02x:%02x:%02x:%02x:%02x",
6457 __func__,
6458 mac[0], mac[1], mac[2],
6459 mac[3], mac[4], mac[5]);
6460 return -ENOENT;
6461 }
6462
6463 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6464 {
6465 hddLog(VOS_TRACE_LEVEL_INFO,
6466 "%s: Skip this DEL STA as deauth is in progress::"
6467 "%02x:%02x:%02x:%02x:%02x:%02x",
6468 __func__,
6469 mac[0], mac[1], mac[2],
6470 mac[3], mac[4], mac[5]);
6471 return -ENOENT;
6472 }
6473
6474 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6475
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 hddLog(VOS_TRACE_LEVEL_INFO,
6477 "%s: Delete STA with MAC::"
6478 "%02x:%02x:%02x:%02x:%02x:%02x",
6479 __func__,
6480 mac[0], mac[1], mac[2],
6481 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006482
6483 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6484 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6485 {
6486 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6487 hddLog(VOS_TRACE_LEVEL_INFO,
6488 "%s: STA removal failed for ::"
6489 "%02x:%02x:%02x:%02x:%02x:%02x",
6490 __func__,
6491 mac[0], mac[1], mac[2],
6492 mac[3], mac[4], mac[5]);
6493 return -ENOENT;
6494 }
6495
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 }
6497 }
6498
6499 EXIT();
6500
6501 return 0;
6502}
6503
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006504static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6505 struct net_device *dev, u8 *mac, struct station_parameters *params)
6506{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006507 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006508#ifdef FEATURE_WLAN_TDLS
6509 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006510 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006511 mask = params->sta_flags_mask;
6512
6513 set = params->sta_flags_set;
6514
Lee Hoonkic1262f22013-01-24 21:59:00 -08006515 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6516 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006517
6518 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6519 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006520 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006521 }
6522 }
6523#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006524 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006525}
6526
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006527
6528#ifdef FEATURE_WLAN_LFR
6529static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006530 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006531{
6532#define MAX_PMKSAIDS_IN_CACHE 8
6533 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006534 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006535 tANI_U32 j=0;
6536 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6537 tHalHandle halHandle;
6538 eHalStatus result;
6539 tANI_U8 BSSIDMatched = 0;
6540
Jeff Johnsone7245742012-09-05 17:12:55 -07006541 ENTER();
6542
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006543 // Validate pAdapter
6544 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6545 {
6546 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6547 return -EINVAL;
6548 }
6549
6550 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6551 {
6552 hddLog( LOGE,
6553 "%s: Wlan Load/Unload is in progress", __func__);
6554 return -EBUSY;
6555 }
6556
6557 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6558 {
6559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6560 "%s:LOGP in Progress. Ignore!!!", __func__);
6561 return -EAGAIN;
6562 }
6563
6564 // Retrieve halHandle
6565 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6566
6567 for (j = 0; j < i; j++)
6568 {
6569 if(vos_mem_compare(PMKIDCache[j].BSSID,
6570 pmksa->bssid, WNI_CFG_BSSID_LEN))
6571 {
6572 /* BSSID matched previous entry. Overwrite it. */
6573 BSSIDMatched = 1;
6574 vos_mem_copy(PMKIDCache[j].BSSID,
6575 pmksa->bssid, WNI_CFG_BSSID_LEN);
6576 vos_mem_copy(PMKIDCache[j].PMKID,
6577 pmksa->pmkid,
6578 CSR_RSN_PMKID_SIZE);
6579 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006580 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006581 dump_bssid(pmksa->bssid);
6582 dump_pmkid(halHandle, pmksa->pmkid);
6583 break;
6584 }
6585 }
6586
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006587 /* Check we compared all entries,if then take the first slot now */
6588 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6589
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006590 if (!BSSIDMatched)
6591 {
6592 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6593 vos_mem_copy(PMKIDCache[i].BSSID,
6594 pmksa->bssid, ETHER_ADDR_LEN);
6595 vos_mem_copy(PMKIDCache[i].PMKID,
6596 pmksa->pmkid,
6597 CSR_RSN_PMKID_SIZE);
6598 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006599 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006600 dump_bssid(pmksa->bssid);
6601 dump_pmkid(halHandle, pmksa->pmkid);
6602 // Increment the HDD Local Cache index
6603 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6604 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6605 }
6606
6607
6608 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6609 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006610 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006611 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006612 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006613 // Finally set the PMKSA ID Cache in CSR
6614 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6615 PMKIDCache,
6616 i );
6617 return 0;
6618}
6619
6620
6621static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006622 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006623{
Jeff Johnsone7245742012-09-05 17:12:55 -07006624 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006625 // TODO: Implement this later.
6626 return 0;
6627}
6628
6629static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6630{
Jeff Johnsone7245742012-09-05 17:12:55 -07006631 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006632 // TODO: Implement this later.
6633 return 0;
6634}
6635#endif
6636
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006637#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6638static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6639 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6640{
6641 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6642 hdd_station_ctx_t *pHddStaCtx;
6643
6644 if (NULL == pAdapter)
6645 {
6646 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6647 return -ENODEV;
6648 }
6649
6650 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6651
6652 // Added for debug on reception of Re-assoc Req.
6653 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6654 {
6655 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6656 ftie->ie_len);
6657 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6658 }
6659
6660#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6661 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6662 ftie->ie_len);
6663#endif
6664
6665 // Pass the received FT IEs to SME
6666 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6667 ftie->ie_len);
6668 return 0;
6669}
6670#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006671
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006672#ifdef FEATURE_WLAN_TDLS
6673static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6674 u8 *peer, u8 action_code, u8 dialog_token,
6675 u16 status_code, const u8 *buf, size_t len)
6676{
6677
6678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6679 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006680 u8 peerMac[6];
6681 VOS_STATUS status;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006682 int ret = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006683 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006684
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006685 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006686 {
6687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6688 "Invalid arguments");
6689 return -EINVAL;
6690 }
6691
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006692 if (pHddCtx->isLogpInProgress)
6693 {
6694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6695 "%s:LOGP in Progress. Ignore!!!", __func__);
6696 return -EBUSY;
6697 }
6698
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006699 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006700 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6701 {
6702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6703 "TDLS Disabled in INI OR not enabled in FW.\
6704 Cannot process TDLS commands \n");
6705 return -ENOTSUPP;
6706 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006707
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006708 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
6709 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006710 if (wlan_hdd_tdls_is_progress(pAdapter, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006711 {
6712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6713 "%s: TDLS setup is ongoing. Request declined.", __func__);
6714 return -EPERM;
6715 }
6716 }
6717
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006718 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
6719 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08006720 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006721 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006722 {
6723 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6724 we return error code at 'add_station()'. Hence we have this
6725 check again in addtion to add_station().
6726 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006727 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006728 {
6729 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6730 "%s: TDLS Max peer already connected. Request declined. \n",
6731 __func__);
6732 return -EPERM;
6733 }
6734 else
6735 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006736 /* maximum reached. tweak to send error code to peer and return
6737 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006738 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6739 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6740 "%s: TDLS Max peer already connected send response status %d \n",
6741 __func__,status_code);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006742 ret = -EPERM;
6743 /* fall through to send setup resp with failure status
6744 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006745 }
6746 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006747 else
6748 {
6749 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006750 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006751 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
6752 {
6753 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6754 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
6755 __func__, peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6756 return -EPERM;
6757 }
6758 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006759 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006760 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006761
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006762#ifdef WLAN_FEATURE_TDLS_DEBUG
6763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6764 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6765 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6766 action_code, dialog_token, status_code, len);
6767#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006768
Hoonki Leea34dd892013-02-05 22:56:02 -08006769 /*Except teardown responder will not be used so just make 0*/
6770 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006771 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08006772 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006773 responder = wlan_hdd_tdls_get_responder(pAdapter, peerMac);
6774 if(-1 == responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08006775 {
6776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6777 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6778 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6779 dialog_token, status_code, len);
6780 return -EPERM;
6781 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006782 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006783
Pervinder Singhb4638422013-03-04 22:51:36 -08006784 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006785 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006786 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_CONNECTING);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006787
6788 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
6789
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006790 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006791 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006792
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006793 if (VOS_STATUS_SUCCESS != status)
6794 {
6795 if(ret == 0 && /* if failure, don't need to set the progress bit */
6796 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006797 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006798
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6800 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006801 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006802 }
6803
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006804 /* not block discovery request, as it is called from timer callback */
6805 if (SIR_MAC_TDLS_DIS_REQ != action_code)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006806 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006807 long rc;
6808
6809 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006810 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006811
Pervinder Singhb4638422013-03-04 22:51:36 -08006812 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006813 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006814 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006815 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006816 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006817
6818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pervinder Singhb4638422013-03-04 22:51:36 -08006819 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
6820 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006821 return -EPERM;
6822 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006823 }
6824
6825 if (ret)
6826 return ret;
6827
Hoonki Leea34dd892013-02-05 22:56:02 -08006828 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6829 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006830 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006831 }
6832 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6833 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006834 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08006835 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006836
6837 return 0;
6838}
6839
6840static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6841 u8 *peer, enum nl80211_tdls_operation oper)
6842{
6843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6844 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006845#ifdef WLAN_FEATURE_TDLS_DEBUG
6846 const char *tdls_oper_str[]= {
6847 "NL80211_TDLS_DISCOVERY_REQ",
6848 "NL80211_TDLS_SETUP",
6849 "NL80211_TDLS_TEARDOWN",
6850 "NL80211_TDLS_ENABLE_LINK",
6851 "NL80211_TDLS_DISABLE_LINK",
6852 "NL80211_TDLS_UNKONW_OPER"};
6853#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006854
6855 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6856 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006858 "Invalid arguments");
6859 return -EINVAL;
6860 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006861
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006862 if (pHddCtx->isLogpInProgress)
6863 {
6864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6865 "%s:LOGP in Progress. Ignore!!!", __func__);
6866 return -EBUSY;
6867 }
6868
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006869#ifdef WLAN_FEATURE_TDLS_DEBUG
6870 if((int)oper > 4)
6871 oper = 5;
6872
6873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6874 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6875 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6876 tdls_oper_str[(int)oper]);
6877#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006878
6879 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006880 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006881 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006883 "TDLS Disabled in INI OR not enabled in FW.\
6884 Cannot process TDLS commands \n");
6885 return -ENOTSUPP;
6886 }
6887
6888 switch (oper) {
6889 case NL80211_TDLS_ENABLE_LINK:
6890 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006891 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006892 VOS_STATUS status;
6893
6894 if (peer) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006895 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006896
6897 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006898 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006899 __func__, peer[0], peer[1],
6900 peer[2], peer[3],
6901 peer[4], peer[5] );
6902
Hoonki Lee387663d2013-02-05 18:08:43 -08006903 if ( NULL == pTdlsPeer ) {
6904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6905 __func__, peer[0], peer[1],
6906 peer[2], peer[3],
6907 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006908 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006909 }
6910
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006911 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
6912 {
6913 /* start TDLS client registration with TL */
6914 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006915 wlan_hdd_tdls_increment_peer_count(pAdapter);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006916 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006917 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006918 }
Chilam NG571c65a2013-01-19 12:27:36 +05306919
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006920 } else {
6921 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6922 }
6923 }
6924 break;
6925 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006926 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006927 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006928
6929 if(NULL != curr_peer)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006930 {
6931 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6932 pAdapter->sessionId, peer );
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08006933 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08006934 }
6935 else
6936 {
6937 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6938 "%s: TDLS Peer Station doesn't exist \n",__func__);
6939 }
6940 return 0;
6941 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006942 case NL80211_TDLS_TEARDOWN:
6943 case NL80211_TDLS_SETUP:
6944 case NL80211_TDLS_DISCOVERY_REQ:
6945 /* We don't support in-driver setup/teardown/discovery */
6946 return -ENOTSUPP;
6947 default:
6948 return -ENOTSUPP;
6949 }
6950 return 0;
6951}
Chilam NG571c65a2013-01-19 12:27:36 +05306952
6953int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6954 struct net_device *dev, u8 *peer)
6955{
6956 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6957 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6958
6959 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6960 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6961}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006962#endif
6963
Jeff Johnson295189b2012-06-20 16:38:30 -07006964/* cfg80211_ops */
6965static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6966{
6967 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6968 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6969 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6970 .change_station = wlan_hdd_change_station,
6971#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6972 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6973 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6974 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006975#else
6976 .start_ap = wlan_hdd_cfg80211_start_ap,
6977 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6978 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006979#endif
6980 .change_bss = wlan_hdd_cfg80211_change_bss,
6981 .add_key = wlan_hdd_cfg80211_add_key,
6982 .get_key = wlan_hdd_cfg80211_get_key,
6983 .del_key = wlan_hdd_cfg80211_del_key,
6984 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006986 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006987#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 .scan = wlan_hdd_cfg80211_scan,
6989 .connect = wlan_hdd_cfg80211_connect,
6990 .disconnect = wlan_hdd_cfg80211_disconnect,
6991 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6992 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6993 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6994 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6995 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07006996 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6997 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6998 .mgmt_tx = wlan_hdd_action,
6999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7000 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7001 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7002 .set_txq_params = wlan_hdd_set_txq_params,
7003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 .get_station = wlan_hdd_cfg80211_get_station,
7005 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7006 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007007 .add_station = wlan_hdd_cfg80211_add_station,
7008#ifdef FEATURE_WLAN_LFR
7009 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7010 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7011 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7012#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007013#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7014 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7015#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007016#ifdef FEATURE_WLAN_TDLS
7017 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7018 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7019#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007020};
7021