blob: 1634b929bcd3af8e15b8a2eb6540f9c366aef41e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**========================================================================
43
44 \file wlan_hdd_cfg80211.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 21/12/09 Ashwani Created module.
69
70 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
71 Ganesh K
72 ==========================================================================*/
73
74#ifdef CONFIG_CFG80211
75
76#include <linux/version.h>
77#include <linux/module.h>
78#include <linux/kernel.h>
79#include <linux/init.h>
80#include <linux/wireless.h>
81#include <wlan_hdd_includes.h>
82#include <net/arp.h>
83#include <net/cfg80211.h>
84#include <linux/wireless.h>
85#include <wlan_hdd_wowl.h>
86#include <aniGlobal.h>
87#include "ccmApi.h"
88#include "sirParams.h"
89#include "dot11f.h"
90#include "wlan_hdd_assoc.h"
91#include "wlan_hdd_wext.h"
92#include "sme_Api.h"
93#include "wlan_hdd_p2p.h"
94#include "wlan_hdd_cfg80211.h"
95#include "wlan_hdd_hostapd.h"
96#include "sapInternal.h"
97#include "wlan_hdd_softap_tx_rx.h"
98#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053099#include "wlan_hdd_assoc.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#ifdef WLAN_BTAMP_FEATURE
101#include "bap_hdd_misc.h"
102#endif
103#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800104#ifdef FEATURE_WLAN_TDLS
105#include "wlan_hdd_tdls.h"
106#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +0530107#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define g_mode_rates_size (12)
110#define a_mode_rates_size (8)
111#define FREQ_BASE_80211G (2407)
112#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700113#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
115 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
116
117#define HDD2GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_2GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD5GHZCHAN(freq, chan, flag) { \
127 .band = IEEE80211_BAND_5GHZ, \
128 .center_freq = (freq), \
129 .hw_value = (chan),\
130 .flags = (flag), \
131 .max_antenna_gain = 0 ,\
132 .max_power = 30, \
133}
134
135#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
136{\
137 .bitrate = rate, \
138 .hw_value = rate_id, \
139 .flags = flag, \
140}
141
Lee Hoonkic1262f22013-01-24 21:59:00 -0800142#ifndef WLAN_FEATURE_TDLS_DEBUG
143#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
144#else
145#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
146#endif
147
Jeff Johnson295189b2012-06-20 16:38:30 -0700148static const u32 hdd_cipher_suites[] =
149{
150 WLAN_CIPHER_SUITE_WEP40,
151 WLAN_CIPHER_SUITE_WEP104,
152 WLAN_CIPHER_SUITE_TKIP,
153#ifdef FEATURE_WLAN_CCX
154#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
155 WLAN_CIPHER_SUITE_KRK,
156 WLAN_CIPHER_SUITE_CCMP,
157#else
158 WLAN_CIPHER_SUITE_CCMP,
159#endif
160#ifdef FEATURE_WLAN_WAPI
161 WLAN_CIPHER_SUITE_SMS4,
162#endif
163};
164
165static inline int is_broadcast_ether_addr(const u8 *addr)
166{
167 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
168 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
169}
170
171static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
172{
173 HDD2GHZCHAN(2412, 1, 0) ,
174 HDD2GHZCHAN(2417, 2, 0) ,
175 HDD2GHZCHAN(2422, 3, 0) ,
176 HDD2GHZCHAN(2427, 4, 0) ,
177 HDD2GHZCHAN(2432, 5, 0) ,
178 HDD2GHZCHAN(2437, 6, 0) ,
179 HDD2GHZCHAN(2442, 7, 0) ,
180 HDD2GHZCHAN(2447, 8, 0) ,
181 HDD2GHZCHAN(2452, 9, 0) ,
182 HDD2GHZCHAN(2457, 10, 0) ,
183 HDD2GHZCHAN(2462, 11, 0) ,
184 HDD2GHZCHAN(2467, 12, 0) ,
185 HDD2GHZCHAN(2472, 13, 0) ,
186 HDD2GHZCHAN(2484, 14, 0) ,
187};
188
189#ifdef WLAN_FEATURE_P2P
190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
196#endif
197
198static struct ieee80211_channel hdd_channels_5_GHZ[] =
199{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700200 HDD5GHZCHAN(4920, 240, 0) ,
201 HDD5GHZCHAN(4940, 244, 0) ,
202 HDD5GHZCHAN(4960, 248, 0) ,
203 HDD5GHZCHAN(4980, 252, 0) ,
204 HDD5GHZCHAN(5040, 208, 0) ,
205 HDD5GHZCHAN(5060, 212, 0) ,
206 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 HDD5GHZCHAN(5180, 36, 0) ,
208 HDD5GHZCHAN(5200, 40, 0) ,
209 HDD5GHZCHAN(5220, 44, 0) ,
210 HDD5GHZCHAN(5240, 48, 0) ,
211 HDD5GHZCHAN(5260, 52, 0) ,
212 HDD5GHZCHAN(5280, 56, 0) ,
213 HDD5GHZCHAN(5300, 60, 0) ,
214 HDD5GHZCHAN(5320, 64, 0) ,
215 HDD5GHZCHAN(5500,100, 0) ,
216 HDD5GHZCHAN(5520,104, 0) ,
217 HDD5GHZCHAN(5540,108, 0) ,
218 HDD5GHZCHAN(5560,112, 0) ,
219 HDD5GHZCHAN(5580,116, 0) ,
220 HDD5GHZCHAN(5600,120, 0) ,
221 HDD5GHZCHAN(5620,124, 0) ,
222 HDD5GHZCHAN(5640,128, 0) ,
223 HDD5GHZCHAN(5660,132, 0) ,
224 HDD5GHZCHAN(5680,136, 0) ,
225 HDD5GHZCHAN(5700,140, 0) ,
226 HDD5GHZCHAN(5745,149, 0) ,
227 HDD5GHZCHAN(5765,153, 0) ,
228 HDD5GHZCHAN(5785,157, 0) ,
229 HDD5GHZCHAN(5805,161, 0) ,
230 HDD5GHZCHAN(5825,165, 0) ,
231};
232
233static struct ieee80211_rate g_mode_rates[] =
234{
235 HDD_G_MODE_RATETAB(10, 0x1, 0),
236 HDD_G_MODE_RATETAB(20, 0x2, 0),
237 HDD_G_MODE_RATETAB(55, 0x4, 0),
238 HDD_G_MODE_RATETAB(110, 0x8, 0),
239 HDD_G_MODE_RATETAB(60, 0x10, 0),
240 HDD_G_MODE_RATETAB(90, 0x20, 0),
241 HDD_G_MODE_RATETAB(120, 0x40, 0),
242 HDD_G_MODE_RATETAB(180, 0x80, 0),
243 HDD_G_MODE_RATETAB(240, 0x100, 0),
244 HDD_G_MODE_RATETAB(360, 0x200, 0),
245 HDD_G_MODE_RATETAB(480, 0x400, 0),
246 HDD_G_MODE_RATETAB(540, 0x800, 0),
247};
248
249static struct ieee80211_rate a_mode_rates[] =
250{
251 HDD_G_MODE_RATETAB(60, 0x10, 0),
252 HDD_G_MODE_RATETAB(90, 0x20, 0),
253 HDD_G_MODE_RATETAB(120, 0x40, 0),
254 HDD_G_MODE_RATETAB(180, 0x80, 0),
255 HDD_G_MODE_RATETAB(240, 0x100, 0),
256 HDD_G_MODE_RATETAB(360, 0x200, 0),
257 HDD_G_MODE_RATETAB(480, 0x400, 0),
258 HDD_G_MODE_RATETAB(540, 0x800, 0),
259};
260
261static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
262{
263 .channels = hdd_channels_2_4_GHZ,
264 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
265 .band = IEEE80211_BAND_2GHZ,
266 .bitrates = g_mode_rates,
267 .n_bitrates = g_mode_rates_size,
268 .ht_cap.ht_supported = 1,
269 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
270 | IEEE80211_HT_CAP_GRN_FLD
271 | IEEE80211_HT_CAP_DSSSCCK40
272 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
273 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
274 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
275 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
276 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
277 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
278};
279
280#ifdef WLAN_FEATURE_P2P
281static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
282{
283 .channels = hdd_social_channels_2_4_GHZ,
284 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
285 .band = IEEE80211_BAND_2GHZ,
286 .bitrates = g_mode_rates,
287 .n_bitrates = g_mode_rates_size,
288 .ht_cap.ht_supported = 1,
289 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
290 | IEEE80211_HT_CAP_GRN_FLD
291 | IEEE80211_HT_CAP_DSSSCCK40
292 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
293 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
294 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
295 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
296 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
297 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
298};
299#endif
300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
322/* This structure contain information what kind of frame are expected in
323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
341#ifdef WLAN_FEATURE_P2P
342 [NL80211_IFTYPE_P2P_CLIENT] = {
343 .tx = 0xffff,
344 .rx = BIT(SIR_MAC_MGMT_ACTION) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ),
346 },
347 [NL80211_IFTYPE_P2P_GO] = {
348 /* This is also same as for SoftAP */
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
351 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
352 BIT(SIR_MAC_MGMT_PROBE_REQ) |
353 BIT(SIR_MAC_MGMT_DISASSOC) |
354 BIT(SIR_MAC_MGMT_AUTH) |
355 BIT(SIR_MAC_MGMT_DEAUTH) |
356 BIT(SIR_MAC_MGMT_ACTION),
357 },
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700359};
360
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
362#ifdef WLAN_FEATURE_P2P
363static const struct ieee80211_iface_limit
364wlan_hdd_iface_limit[] = {
365 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800366 /* max = 3 ; Our driver create two interfaces during driver init
367 * wlan0 and p2p0 interfaces. p2p0 is considered as station
368 * interface until a group is formed. In JB architecture, once the
369 * group is formed, interface type of p2p0 is changed to P2P GO or
370 * Client.
371 * When supplicant remove the group, it first issue a set interface
372 * cmd to change the mode back to Station. In JB this works fine as
373 * we advertize two station type interface during driver init.
374 * Some vendors create separate interface for P2P GO/Client,
375 * after group formation(Third one). But while group remove
376 * supplicant first tries to change the mode(3rd interface) to STATION
377 * But as we advertized only two sta type interfaces nl80211 was
378 * returning error for the third one which was leading to failure in
379 * delete interface. Ideally while removing the group, supplicant
380 * should not try to change the 3rd interface mode to Station type.
381 * Till we get a fix in wpa_supplicant, we advertize max STA
382 * interface type to 3
383 */
384 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800385 .types = BIT(NL80211_IFTYPE_STATION),
386 },
387 {
388 .max = 1,
389 .types = BIT(NL80211_IFTYPE_AP),
390 },
391 {
392 .max = 1,
393 .types = BIT(NL80211_IFTYPE_P2P_GO) |
394 BIT(NL80211_IFTYPE_P2P_CLIENT),
395 },
396};
397
398/* By default, only single channel concurrency is allowed */
399static struct ieee80211_iface_combination
400wlan_hdd_iface_combination = {
401 .limits = wlan_hdd_iface_limit,
402 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800403 /*
404 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
405 * and p2p0 interfaces during driver init
406 * Some vendors create separate interface for P2P operations.
407 * wlan0: STA interface
408 * p2p0: P2P Device interface, action frames goes
409 * through this interface.
410 * p2p-xx: P2P interface, After GO negotiation this interface is
411 * created for p2p operations(GO/CLIENT interface).
412 */
413 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
415 .beacon_int_infra_match = false,
416};
417#endif
418#endif
419
Jeff Johnson295189b2012-06-20 16:38:30 -0700420static struct cfg80211_ops wlan_hdd_cfg80211_ops;
421
422/* Data rate 100KBPS based on IE Index */
423struct index_data_rate_type
424{
425 v_U8_t beacon_rate_index;
426 v_U16_t supported_rate[4];
427};
428
429/* 11B, 11G Rate table include Basic rate and Extended rate
430 The IDX field is the rate index
431 The HI field is the rate when RSSI is strong or being ignored
432 (in this case we report actual rate)
433 The MID field is the rate when RSSI is moderate
434 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
435 The LO field is the rate when RSSI is low
436 (in this case we don't report rates, actual current rate used)
437 */
438static const struct
439{
440 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700441 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700442} supported_data_rate[] =
443{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700444/* IDX HI HM LM LO (RSSI-based index */
445 {2, { 10, 10, 10, 0}},
446 {4, { 20, 20, 10, 0}},
447 {11, { 55, 20, 10, 0}},
448 {12, { 60, 55, 20, 0}},
449 {18, { 90, 55, 20, 0}},
450 {22, {110, 55, 20, 0}},
451 {24, {120, 90, 60, 0}},
452 {36, {180, 120, 60, 0}},
453 {44, {220, 180, 60, 0}},
454 {48, {240, 180, 90, 0}},
455 {66, {330, 180, 90, 0}},
456 {72, {360, 240, 90, 0}},
457 {96, {480, 240, 120, 0}},
458 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700459};
460
461/* MCS Based rate table */
462static struct index_data_rate_type supported_mcs_rate[] =
463{
464/* MCS L20 L40 S20 S40 */
465 {0, {65, 135, 72, 150}},
466 {1, {130, 270, 144, 300}},
467 {2, {195, 405, 217, 450}},
468 {3, {260, 540, 289, 600}},
469 {4, {390, 810, 433, 900}},
470 {5, {520, 1080, 578, 1200}},
471 {6, {585, 1215, 650, 1350}},
472 {7, {650, 1350, 722, 1500}}
473};
474
475extern struct net_device_ops net_ops_struct;
476
477/*
478 * FUNCTION: wlan_hdd_cfg80211_init
479 * This function is called by hdd_wlan_startup()
480 * during initialization.
481 * This function is used to initialize and register wiphy structure.
482 */
483struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
484{
485 struct wiphy *wiphy;
486 ENTER();
487
488 /*
489 * Create wiphy device
490 */
491 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
492
493 if (!wiphy)
494 {
495 /* Print error and jump into err label and free the memory */
496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
497 return NULL;
498 }
499
500 return wiphy;
501}
502
503/*
504 * FUNCTION: wlan_hdd_cfg80211_update_band
505 * This function is called from the supplicant through a
506 * private ioctl to change the band value
507 */
508int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
509{
Jeff Johnsone7245742012-09-05 17:12:55 -0700510 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700511 switch(eBand)
512 {
513 case eCSR_BAND_24:
514 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
515 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
516 break;
517 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700518#ifdef WLAN_FEATURE_P2P
519 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
520#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700521 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700523 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
524 break;
525 case eCSR_BAND_ALL:
526 default:
527 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
528 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
529 }
530 return 0;
531}
532/*
533 * FUNCTION: wlan_hdd_cfg80211_init
534 * This function is called by hdd_wlan_startup()
535 * during initialization.
536 * This function is used to initialize and register wiphy structure.
537 */
538int wlan_hdd_cfg80211_register(struct device *dev,
539 struct wiphy *wiphy,
540 hdd_config_t *pCfg
541 )
542{
Jeff Johnsone7245742012-09-05 17:12:55 -0700543 ENTER();
544
Jeff Johnson295189b2012-06-20 16:38:30 -0700545 /* Now bind the underlying wlan device with wiphy */
546 set_wiphy_dev(wiphy, dev);
547
548 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
549
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700550 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700553 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
554 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
555 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700556 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700557#endif
James Zmuda77fb5ae2013-01-29 08:00:17 -0800558#ifdef FEATURE_WLAN_LFR
559 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
560#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800561#ifdef FEATURE_WLAN_TDLS
562 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
563 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
564#endif
565
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700566 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
567 driver can still register regulatory callback and
568 it will get CRDA setting in wiphy->band[], but
569 driver need to determine what to do with both
570 regulatory settings */
571 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700572
Jeff Johnson295189b2012-06-20 16:38:30 -0700573 wiphy->max_scan_ssids = MAX_SCAN_SSID;
574
575 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
576
577 /* Supports STATION & AD-HOC modes right now */
578 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
579 | BIT(NL80211_IFTYPE_ADHOC)
580#ifdef WLAN_FEATURE_P2P
581 | BIT(NL80211_IFTYPE_P2P_CLIENT)
582 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700584 | BIT(NL80211_IFTYPE_AP);
585
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
587#ifdef WLAN_FEATURE_P2P
588 if( pCfg->enableMCC )
589 {
590 /* Currently, supports up to two channels */
591 wlan_hdd_iface_combination.num_different_channels = 2;
592
593 if( !pCfg->allowMCCGODiffBI )
594 wlan_hdd_iface_combination.beacon_int_infra_match = true;
595
596 }
597 wiphy->iface_combinations = &wlan_hdd_iface_combination;
598 wiphy->n_iface_combinations = 1;
599#endif
600#endif
601
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 /* Before registering we need to update the ht capabilitied based
603 * on ini values*/
604 if( !pCfg->ShortGI20MhzEnable )
605 {
606 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
607 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
608 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
609 }
610
611 if( !pCfg->ShortGI40MhzEnable )
612 {
613 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
614 }
615
616 if( !pCfg->nChannelBondingMode5GHz )
617 {
618 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
619 }
620
621 /*Initialize band capability*/
622 switch(pCfg->nBandCapability)
623 {
624 case eCSR_BAND_24:
625 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
626 break;
627 case eCSR_BAND_5G:
628#ifdef WLAN_FEATURE_P2P
629 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
630#endif
631 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
632 break;
633 case eCSR_BAND_ALL:
634 default:
635 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
636 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
637 }
638 /*Initialise the supported cipher suite details*/
639 wiphy->cipher_suites = hdd_cipher_suites;
640 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
641
642 /*signal strength in mBm (100*dBm) */
643 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
644
645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
646#ifdef WLAN_FEATURE_P2P
647 wiphy->max_remain_on_channel_duration = 1000;
648#endif
649#endif
650
651 /* Register our wiphy dev with cfg80211 */
652 if (0 > wiphy_register(wiphy))
653 {
654 /* print eror */
655 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
656 return -EIO;
657 }
658
659 EXIT();
660 return 0;
661}
662
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700663/* In this function we will try to get default country code from crda.
664 If the gCrdaDefaultCountryCode is configured in ini file,
665 we will try to call user space crda to get the regulatory settings for
666 that country. We will timeout if we can't get it from crda.
667 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
668*/
669int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
670{
671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
672 if (memcmp(pCfg->crdaDefaultCountryCode,
673 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
674 {
675 init_completion(&pHddCtx->driver_crda_req);
676 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
677 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
678 CRDA_WAIT_TIME);
679 }
680 return 0;
681}
682
Jeff Johnson295189b2012-06-20 16:38:30 -0700683/* In this function we will do all post VOS start initialization.
684 In this function we will register for all frame in which supplicant
685 is interested.
686*/
687void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
688{
689#ifdef WLAN_FEATURE_P2P
690 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
691 /* Register for all P2P action, public action etc frames */
692 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
693
Jeff Johnsone7245742012-09-05 17:12:55 -0700694 ENTER();
695
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 /* Right now we are registering these frame when driver is getting
697 initialized. Once we will move to 2.6.37 kernel, in which we have
698 frame register ops, we will move this code as a part of that */
699 /* GAS Initial Request */
700 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
701 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
702
703 /* GAS Initial Response */
704 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
705 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
706
707 /* GAS Comeback Request */
708 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
709 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
710
711 /* GAS Comeback Response */
712 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
713 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
714
715 /* P2P Public Action */
716 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
717 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
718 P2P_PUBLIC_ACTION_FRAME_SIZE );
719
720 /* P2P Action */
721 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
722 (v_U8_t*)P2P_ACTION_FRAME,
723 P2P_ACTION_FRAME_SIZE );
724#endif /* WLAN_FEATURE_P2P */
725}
726
727void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
728{
729#ifdef WLAN_FEATURE_P2P
730 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
731 /* Register for all P2P action, public action etc frames */
732 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
733
Jeff Johnsone7245742012-09-05 17:12:55 -0700734 ENTER();
735
Jeff Johnson295189b2012-06-20 16:38:30 -0700736 /* Right now we are registering these frame when driver is getting
737 initialized. Once we will move to 2.6.37 kernel, in which we have
738 frame register ops, we will move this code as a part of that */
739 /* GAS Initial Request */
740
741 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
742 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
743
744 /* GAS Initial Response */
745 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
746 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
747
748 /* GAS Comeback Request */
749 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
750 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
751
752 /* GAS Comeback Response */
753 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
754 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
755
756 /* P2P Public Action */
757 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
758 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
759 P2P_PUBLIC_ACTION_FRAME_SIZE );
760
761 /* P2P Action */
762 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
763 (v_U8_t*)P2P_ACTION_FRAME,
764 P2P_ACTION_FRAME_SIZE );
765#endif /* WLAN_FEATURE_P2P */
766}
767
768#ifdef FEATURE_WLAN_WAPI
769void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
770 const u8 *mac_addr, u8 *key , int key_Len)
771{
772 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
773 tCsrRoamSetKey setKey;
774 v_BOOL_t isConnected = TRUE;
775 int status = 0;
776 v_U32_t roamId= 0xFF;
777 tANI_U8 *pKeyPtr = NULL;
778 int n = 0;
779
780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
781 __func__,pAdapter->device_mode);
782
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530783 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 setKey.keyId = key_index; // Store Key ID
785 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
786 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
787 setKey.paeRole = 0 ; // the PAE role
788 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
789 {
790 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
791 }
792 else
793 {
794 isConnected = hdd_connIsConnected(pHddStaCtx);
795 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
796 }
797 setKey.keyLength = key_Len;
798 pKeyPtr = setKey.Key;
799 memcpy( pKeyPtr, key, key_Len);
800
801 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
802 __func__, key_Len);
803 for (n = 0 ; n < key_Len; n++)
804 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
805 __func__,n,setKey.Key[n]);
806
807 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
808 if ( isConnected )
809 {
810 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
811 pAdapter->sessionId, &setKey, &roamId );
812 }
813 if ( status != 0 )
814 {
815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
816 "[%4d] sme_RoamSetKey returned ERROR status= %d",
817 __LINE__, status );
818 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
819 }
820}
821#endif /* FEATURE_WLAN_WAPI*/
822
823#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
824int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
825 beacon_data_t **ppBeacon,
826 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700827#else
828int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
829 beacon_data_t **ppBeacon,
830 struct cfg80211_beacon_data *params,
831 int dtim_period)
832#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700833{
834 int size;
835 beacon_data_t *beacon = NULL;
836 beacon_data_t *old = NULL;
837 int head_len,tail_len;
838
Jeff Johnsone7245742012-09-05 17:12:55 -0700839 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 if (params->head && !params->head_len)
841 return -EINVAL;
842
843 old = pAdapter->sessionCtx.ap.beacon;
844
845 if (!params->head && !old)
846 return -EINVAL;
847
848 if (params->tail && !params->tail_len)
849 return -EINVAL;
850
851#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
852 /* Kernel 3.0 is not updating dtim_period for set beacon */
853 if (!params->dtim_period)
854 return -EINVAL;
855#endif
856
857 if(params->head)
858 head_len = params->head_len;
859 else
860 head_len = old->head_len;
861
862 if(params->tail || !old)
863 tail_len = params->tail_len;
864 else
865 tail_len = old->tail_len;
866
867 size = sizeof(beacon_data_t) + head_len + tail_len;
868
869 beacon = kzalloc(size, GFP_KERNEL);
870
871 if( beacon == NULL )
872 return -ENOMEM;
873
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700874#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700875 if(params->dtim_period || !old )
876 beacon->dtim_period = params->dtim_period;
877 else
878 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700879#else
880 if(dtim_period || !old )
881 beacon->dtim_period = dtim_period;
882 else
883 beacon->dtim_period = old->dtim_period;
884#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700885
886 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
887 beacon->tail = beacon->head + head_len;
888 beacon->head_len = head_len;
889 beacon->tail_len = tail_len;
890
891 if(params->head) {
892 memcpy (beacon->head,params->head,beacon->head_len);
893 }
894 else {
895 if(old)
896 memcpy (beacon->head,old->head,beacon->head_len);
897 }
898
899 if(params->tail) {
900 memcpy (beacon->tail,params->tail,beacon->tail_len);
901 }
902 else {
903 if(old)
904 memcpy (beacon->tail,old->tail,beacon->tail_len);
905 }
906
907 *ppBeacon = beacon;
908
909 kfree(old);
910
911 return 0;
912
913}
Jeff Johnson295189b2012-06-20 16:38:30 -0700914
915v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
916{
917 int left = length;
918 v_U8_t *ptr = pIes;
919 v_U8_t elem_id,elem_len;
920
921 while(left >= 2)
922 {
923 elem_id = ptr[0];
924 elem_len = ptr[1];
925 left -= 2;
926 if(elem_len > left)
927 {
928 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700929 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700930 eid,elem_len,left);
931 return NULL;
932 }
933 if (elem_id == eid)
934 {
935 return ptr;
936 }
937
938 left -= elem_len;
939 ptr += (elem_len + 2);
940 }
941 return NULL;
942}
943
Jeff Johnson295189b2012-06-20 16:38:30 -0700944/* Check if rate is 11g rate or not */
945static int wlan_hdd_rate_is_11g(u8 rate)
946{
947 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
948 u8 i;
949 for (i = 0; i < 8; i++)
950 {
951 if(rate == gRateArray[i])
952 return TRUE;
953 }
954 return FALSE;
955}
956
957/* Check for 11g rate and set proper 11g only mode */
958static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
959 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
960{
961 u8 i, num_rates = pIe[0];
962
963 pIe += 1;
964 for ( i = 0; i < num_rates; i++)
965 {
966 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
967 {
968 /* If rate set have 11g rate than change the mode to 11G */
969 *pSapHw_mode = eSAP_DOT11_MODE_11g;
970 if (pIe[i] & BASIC_RATE_MASK)
971 {
972 /* If we have 11g rate as basic rate, it means mode
973 is 11g only mode.
974 */
975 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
976 *pCheckRatesfor11g = FALSE;
977 }
978 }
979 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
980 {
981 *require_ht = TRUE;
982 }
983 }
984 return;
985}
986
987static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
988{
989 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
990 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
991 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
992 u8 checkRatesfor11g = TRUE;
993 u8 require_ht = FALSE;
994 u8 *pIe=NULL;
995
996 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
997
998 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
999 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1000 if (pIe != NULL)
1001 {
1002 pIe += 1;
1003 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1004 &pConfig->SapHw_mode);
1005 }
1006
1007 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1008 WLAN_EID_EXT_SUPP_RATES);
1009 if (pIe != NULL)
1010 {
1011
1012 pIe += 1;
1013 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1014 &pConfig->SapHw_mode);
1015 }
1016
1017 if( pConfig->channel > 14 )
1018 {
1019 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1020 }
1021
1022 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1023 WLAN_EID_HT_CAPABILITY);
1024
1025 if(pIe)
1026 {
1027 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1028 if(require_ht)
1029 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1030 }
1031}
1032
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001033#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001034static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1035 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001036#else
1037static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1038 struct cfg80211_beacon_data *params)
1039#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001040{
1041 v_U8_t *genie;
1042 v_U8_t total_ielen = 0, ielen = 0;
1043 v_U8_t *pIe = NULL;
1044 v_U8_t addIE[1] = {0};
1045 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Jeff Johnsone7245742012-09-05 17:12:55 -07001046 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001047
1048 genie = vos_mem_malloc(MAX_GENIE_LEN);
1049
1050 if(genie == NULL) {
1051
1052 return -ENOMEM;
1053 }
1054
1055 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1056
1057 if(pIe)
1058 {
1059 /*Copy the wps IE*/
1060 ielen = pIe[1] + 2;
1061 if( ielen <=MAX_GENIE_LEN)
1062 {
1063 vos_mem_copy(genie, pIe, ielen);
1064 }
1065 else
1066 {
1067 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001068 ret = -EINVAL;
1069 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001070 }
1071 total_ielen = ielen;
1072 }
1073
1074#ifdef WLAN_FEATURE_WFD
1075 pIe = wlan_hdd_get_wfd_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1076
1077 if(pIe)
1078 {
1079 ielen = pIe[1] + 2;
1080 if(total_ielen + ielen <= MAX_GENIE_LEN) {
1081 vos_mem_copy(&genie[total_ielen],pIe,(pIe[1] + 2));
1082 }
1083 else {
1084 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie + P2p Ie + Wfd Ie Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001085 ret = -EINVAL;
1086 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 }
1088 total_ielen += ielen;
1089 }
1090#endif
1091
1092#ifdef WLAN_FEATURE_P2P
1093 pIe = wlan_hdd_get_p2p_ie_ptr(pBeacon->tail,pBeacon->tail_len);
1094
1095 if(pIe)
1096 {
1097 ielen = pIe[1] + 2;
1098 if(total_ielen + ielen <= MAX_GENIE_LEN)
1099 {
1100 vos_mem_copy(&genie[total_ielen], pIe, (pIe[1] + 2));
1101 }
1102 else
1103 {
1104 hddLog( VOS_TRACE_LEVEL_ERROR,
1105 "**Wps Ie+ P2pIE Length is too big***\n");
Jeff Johnsone7245742012-09-05 17:12:55 -07001106 ret = -EINVAL;
1107 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 }
1109 total_ielen += ielen;
1110 }
1111#endif
1112
1113 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1114 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1115 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1116 {
1117 hddLog(LOGE,
1118 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001119 ret = -EINVAL;
1120 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001121 }
1122
1123 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1124 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1125 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1126 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1127 ==eHAL_STATUS_FAILURE)
1128 {
1129 hddLog(LOGE,
1130 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001131 ret = -EINVAL;
1132 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001133 }
1134
1135 // Added for ProResp IE
1136 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1137 {
1138 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1139 u8 probe_rsp_ie_len[3] = {0};
1140 u8 counter = 0;
1141 /* Check Probe Resp Length if it is greater then 255 then Store
1142 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1143 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1144 Store More then 255 bytes into One Variable.
1145 */
1146 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1147 {
1148 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1149 {
1150 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1151 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1152 }
1153 else
1154 {
1155 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1156 rem_probe_resp_ie_len = 0;
1157 }
1158 }
1159
1160 rem_probe_resp_ie_len = 0;
1161
1162 if (probe_rsp_ie_len[0] > 0)
1163 {
1164 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1165 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1166 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1167 probe_rsp_ie_len[0], NULL,
1168 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1169 {
1170 hddLog(LOGE,
1171 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001172 ret = -EINVAL;
1173 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 }
1175 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1176 }
1177
1178 if (probe_rsp_ie_len[1] > 0)
1179 {
1180 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1181 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1182 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1183 probe_rsp_ie_len[1], NULL,
1184 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1185 {
1186 hddLog(LOGE,
1187 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001188 ret = -EINVAL;
1189 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 }
1191 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1192 }
1193
1194 if (probe_rsp_ie_len[2] > 0)
1195 {
1196 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1197 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1198 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1199 probe_rsp_ie_len[2], NULL,
1200 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1201 {
1202 hddLog(LOGE,
1203 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001204 ret = -EINVAL;
1205 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001206 }
1207 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1208 }
1209
1210 if (probe_rsp_ie_len[1] == 0 )
1211 {
1212 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1213 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1214 eANI_BOOLEAN_FALSE) )
1215 {
1216 hddLog(LOGE,
1217 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1218 }
1219 }
1220
1221 if (probe_rsp_ie_len[2] == 0 )
1222 {
1223 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1224 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1225 eANI_BOOLEAN_FALSE) )
1226 {
1227 hddLog(LOGE,
1228 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1229 }
1230 }
1231
1232 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1233 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1234 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1235 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1236 == eHAL_STATUS_FAILURE)
1237 {
1238 hddLog(LOGE,
1239 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001240 ret = -EINVAL;
1241 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001242 }
1243 }
1244 else
1245 {
1246 // Reset WNI_CFG_PROBE_RSP Flags
1247 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1248
1249 hddLog(VOS_TRACE_LEVEL_INFO,
1250 "%s: No Probe Response IE received in set beacon",
1251 __func__);
1252 }
1253
1254 // Added for AssocResp IE
1255 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1256 {
1257 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1258 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1259 params->assocresp_ies_len, NULL,
1260 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1261 {
1262 hddLog(LOGE,
1263 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001264 ret = -EINVAL;
1265 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001266 }
1267
1268 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1269 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1270 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1271 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1272 == eHAL_STATUS_FAILURE)
1273 {
1274 hddLog(LOGE,
1275 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001276 ret = -EINVAL;
1277 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001278 }
1279 }
1280 else
1281 {
1282 hddLog(VOS_TRACE_LEVEL_INFO,
1283 "%s: No Assoc Response IE received in set beacon",
1284 __func__);
1285
1286 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1287 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1288 eANI_BOOLEAN_FALSE) )
1289 {
1290 hddLog(LOGE,
1291 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1292 }
1293 }
1294
Jeff Johnsone7245742012-09-05 17:12:55 -07001295done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001296 vos_mem_free(genie);
1297 return 0;
1298}
Jeff Johnson295189b2012-06-20 16:38:30 -07001299
1300/*
1301 * FUNCTION: wlan_hdd_validate_operation_channel
1302 * called by wlan_hdd_cfg80211_start_bss() and
1303 * wlan_hdd_cfg80211_set_channel()
1304 * This function validates whether given channel is part of valid
1305 * channel list.
1306 */
1307static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1308{
1309
1310 v_U32_t num_ch = 0;
1311 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1312 u32 indx = 0;
1313 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301314 v_U8_t fValidChannel = FALSE, count = 0;
1315 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07001316
1317 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1318
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301319 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001320 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301321 /* Validate the channel */
1322 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301324 if ( channel == rfChannels[count].channelNum )
1325 {
1326 fValidChannel = TRUE;
1327 break;
1328 }
1329 }
1330 if (fValidChannel != TRUE)
1331 {
1332 hddLog(VOS_TRACE_LEVEL_ERROR,
1333 "%s: Invalid Channel [%d]", __func__, channel);
1334 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001335 }
1336 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301337 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301339 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1340 valid_ch, &num_ch))
1341 {
1342 hddLog(VOS_TRACE_LEVEL_ERROR,
1343 "%s: failed to get valid channel list", __func__);
1344 return VOS_STATUS_E_FAILURE;
1345 }
1346 for (indx = 0; indx < num_ch; indx++)
1347 {
1348 if (channel == valid_ch[indx])
1349 {
1350 break;
1351 }
1352 }
1353
1354 if (indx >= num_ch)
1355 {
1356 hddLog(VOS_TRACE_LEVEL_ERROR,
1357 "%s: Invalid Channel [%d]", __func__, channel);
1358 return VOS_STATUS_E_FAILURE;
1359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 }
1361 return VOS_STATUS_SUCCESS;
1362
1363}
1364
Viral Modi3a32cc52013-02-08 11:14:52 -08001365/**
1366 * FUNCTION: wlan_hdd_cfg80211_set_channel
1367 * This function is used to set the channel number
1368 */
1369static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1370 struct ieee80211_channel *chan,
1371 enum nl80211_channel_type channel_type
1372 )
1373{
1374 v_U32_t num_ch = 0;
1375 u32 channel = 0;
1376 hdd_adapter_t *pAdapter = NULL;
1377 int freq = chan->center_freq; /* freq is in MHZ */
1378
1379 ENTER();
1380
1381 if( NULL == dev )
1382 {
1383 hddLog(VOS_TRACE_LEVEL_ERROR,
1384 "%s: Called with dev = NULL.\n", __func__);
1385 return -ENODEV;
1386 }
1387 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1388
1389 hddLog(VOS_TRACE_LEVEL_INFO,
1390 "%s: device_mode = %d freq = %d \n",__func__,
1391 pAdapter->device_mode, chan->center_freq);
1392 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1393 {
1394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1395 return -EAGAIN;
1396 }
1397
1398 /*
1399 * Do freq to chan conversion
1400 * TODO: for 11a
1401 */
1402
1403 channel = ieee80211_frequency_to_channel(freq);
1404
1405 /* Check freq range */
1406 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1407 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1408 {
1409 hddLog(VOS_TRACE_LEVEL_ERROR,
1410 "%s: Channel [%d] is outside valid range from %d to %d\n",
1411 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1412 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1413 return -EINVAL;
1414 }
1415
1416 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1417
1418 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode)
1419#ifdef WLAN_FEATURE_P2P
1420 && (WLAN_HDD_P2P_GO != pAdapter->device_mode)
1421#endif
1422 )
1423 {
1424 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1425 {
1426 hddLog(VOS_TRACE_LEVEL_ERROR,
1427 "%s: Invalid Channel [%d] \n", __func__, channel);
1428 return -EINVAL;
1429 }
1430 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1431 "%s: set channel to [%d] for device mode =%d",
1432 __func__, channel,pAdapter->device_mode);
1433 }
1434 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
1435#ifdef WLAN_FEATURE_P2P
1436 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
1437#endif
1438 )
1439 {
1440 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1441 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1442 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1443
1444 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1445 {
1446 /* Link is up then return cant set channel*/
1447 hddLog( VOS_TRACE_LEVEL_ERROR,
1448 "%s: IBSS Associated, can't set the channel\n", __func__);
1449 return -EINVAL;
1450 }
1451
1452 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1453 pHddStaCtx->conn_info.operationChannel = channel;
1454 pRoamProfile->ChannelInfo.ChannelList =
1455 &pHddStaCtx->conn_info.operationChannel;
1456 }
1457 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
1458#ifdef WLAN_FEATURE_P2P
1459 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
1460#endif
1461 )
1462 {
1463 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1464
1465 if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
1466 {
1467 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1468
1469 /* If auto channel selection is configured as enable/ 1 then ignore
1470 channel set by supplicant
1471 */
1472 if ( cfg_param->apAutoChannelSelection )
1473 {
1474 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = AUTO_CHANNEL_SELECT;
1475
1476 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1477 "%s: set channel to auto channel (0) for device mode =%d",
1478 __func__, pAdapter->device_mode);
1479 }
1480 }
1481 }
1482 else
1483 {
1484 hddLog(VOS_TRACE_LEVEL_FATAL,
1485 "%s: Invalid device mode failed to set valid channel", __func__);
1486 return -EINVAL;
1487 }
1488 EXIT();
1489 return 0;
1490}
1491
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301492/*
1493 * FUNCTION: wlan_hdd_select_cbmode
1494 * called by wlan_hdd_cfg80211_start_bss() and
1495 * This function selects the cbmode based on primary channel
1496 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001497VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301498{
1499 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001500 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1501 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1502
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301503 if(
1504#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001505 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1506 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301507#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001508 SapHw_mode != eSAP_DOT11_MODE_11n &&
1509 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301510 )
1511 {
1512 return VOS_STATUS_SUCCESS;
1513 }
1514
1515 if (!pConfigIni->nChannelBondingMode5GHz) {
1516 return VOS_STATUS_SUCCESS;
1517 }
1518
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001519 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301520 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1521
1522 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1523
1524#ifdef WLAN_FEATURE_11AC
1525
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001526 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1527 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301528 {
1529 if ( channel== 36 || channel == 52 || channel == 100 ||
1530 channel == 116 || channel == 149 )
1531 {
1532 smeConfig.csrConfig.channelBondingMode5GHz =
1533 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1534 }
1535 else if ( channel == 40 || channel == 56 || channel == 104 ||
1536 channel == 120 || channel == 153 )
1537 {
1538 smeConfig.csrConfig.channelBondingMode5GHz =
1539 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1540 }
1541 else if ( channel == 44 || channel == 60 || channel == 108 ||
1542 channel == 124 || channel == 157 )
1543 {
1544 smeConfig.csrConfig.channelBondingMode5GHz =
1545 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1546 }
1547 else if ( channel == 48 || channel == 64 || channel == 112 ||
1548 channel == 128 || channel == 161 )
1549 {
1550 smeConfig.csrConfig.channelBondingMode5GHz =
1551 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1552 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001553 else if ( channel == 165 )
1554 {
1555 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1556 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301557 }
1558#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001559 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1560 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301561 {
1562 if ( channel== 40 || channel == 48 || channel == 56 ||
1563 channel == 64 || channel == 104 || channel == 112 ||
1564 channel == 120 || channel == 128 || channel == 136 ||
1565 channel == 144 || channel == 153 || channel == 161 )
1566 {
1567 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1568 }
1569 else if ( channel== 36 || channel == 44 || channel == 52 ||
1570 channel == 60 || channel == 100 || channel == 108 ||
1571 channel == 116 || channel == 124 || channel == 132 ||
1572 channel == 140 || channel == 149 || channel == 157 )
1573 {
1574 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1575 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001576 else if ( channel == 165 )
1577 {
1578 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1579 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301580 }
1581 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1582
1583 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1584 return VOS_STATUS_SUCCESS;
1585}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001586
Jeff Johnson295189b2012-06-20 16:38:30 -07001587#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1588static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1589 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001590#else
1591static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1592 struct cfg80211_beacon_data *params,
1593 const u8 *ssid, size_t ssid_len,
1594 enum nl80211_hidden_ssid hidden_ssid)
1595#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001596{
1597 tsap_Config_t *pConfig;
1598 beacon_data_t *pBeacon = NULL;
1599 struct ieee80211_mgmt *pMgmt_frame;
1600 v_U8_t *pIe=NULL;
1601 v_U16_t capab_info;
1602 eCsrAuthType RSNAuthType;
1603 eCsrEncryptionType RSNEncryptType;
1604 eCsrEncryptionType mcRSNEncryptType;
1605 int status = VOS_STATUS_SUCCESS;
1606 tpWLAN_SAPEventCB pSapEventCallback;
1607 hdd_hostapd_state_t *pHostapdState;
1608 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1609 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301610 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 struct qc_mac_acl_entry *acl_entry = NULL;
1612 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001613 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001614
1615 ENTER();
1616
1617 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1618
1619 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1620
1621 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1622
1623 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1624
1625 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1626
1627 //channel is already set in the set_channel Call back
1628 //pConfig->channel = pCommitConfig->channel;
1629
1630 /*Protection parameter to enable or disable*/
1631 pConfig->protEnabled =
1632 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1633
1634 pConfig->dtim_period = pBeacon->dtim_period;
1635
1636 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1637 pConfig->dtim_period);
1638
1639
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001640 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001641 {
1642 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001644 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001646 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001647 pConfig->ieee80211d = 1;
1648 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1649 sme_setRegInfo(hHal, pConfig->countryCode);
1650 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001652 else
1653 {
1654 pConfig->ieee80211d = 0;
1655 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301656 /*
1657 * If auto channel is configured i.e. channel is 0,
1658 * so skip channel validation.
1659 */
1660 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1661 {
1662 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1663 {
1664 hddLog(VOS_TRACE_LEVEL_ERROR,
1665 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1666 return -EINVAL;
1667 }
1668 }
1669 else
1670 {
1671 if(1 != pHddCtx->is_dynamic_channel_range_set)
1672 {
1673 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1674 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1675 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1676 }
1677 pHddCtx->is_dynamic_channel_range_set = 0;
1678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001680 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001681 {
1682 pConfig->ieee80211d = 0;
1683 }
1684 pConfig->authType = eSAP_AUTO_SWITCH;
1685
1686 capab_info = pMgmt_frame->u.beacon.capab_info;
1687
1688 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1689 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1690
1691 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1692
1693 /*Set wps station to configured*/
1694 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1695
1696 if(pIe)
1697 {
1698 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1699 {
1700 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1701 return -EINVAL;
1702 }
1703 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1704 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001705 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 /* Check 15 bit of WPS IE as it contain information for wps state
1707 * WPS state
1708 */
1709 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1710 {
1711 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1712 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1713 {
1714 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1715 }
1716 }
1717 }
1718 else
1719 {
1720 pConfig->wps_state = SAP_WPS_DISABLED;
1721 }
1722 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1723
1724 pConfig->RSNWPAReqIELength = 0;
1725 pConfig->pRSNWPAReqIE = NULL;
1726 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1727 WLAN_EID_RSN);
1728 if(pIe && pIe[1])
1729 {
1730 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1731 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1732 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1733 /* The actual processing may eventually be more extensive than
1734 * this. Right now, just consume any PMKIDs that are sent in
1735 * by the app.
1736 * */
1737 status = hdd_softap_unpackIE(
1738 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1739 &RSNEncryptType,
1740 &mcRSNEncryptType,
1741 &RSNAuthType,
1742 pConfig->pRSNWPAReqIE[1]+2,
1743 pConfig->pRSNWPAReqIE );
1744
1745 if( VOS_STATUS_SUCCESS == status )
1746 {
1747 /* Now copy over all the security attributes you have
1748 * parsed out
1749 * */
1750 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1751 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1752 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1753 = RSNEncryptType;
1754 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1755 "EncryptionType = %d mcEncryptionType = %d\n"),
1756 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1757 }
1758 }
1759
1760 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1761 pBeacon->tail, pBeacon->tail_len);
1762
1763 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1764 {
1765 if (pConfig->pRSNWPAReqIE)
1766 {
1767 /*Mixed mode WPA/WPA2*/
1768 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1769 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1770 }
1771 else
1772 {
1773 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1774 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1775 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1776 status = hdd_softap_unpackIE(
1777 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1778 &RSNEncryptType,
1779 &mcRSNEncryptType,
1780 &RSNAuthType,
1781 pConfig->pRSNWPAReqIE[1]+2,
1782 pConfig->pRSNWPAReqIE );
1783
1784 if( VOS_STATUS_SUCCESS == status )
1785 {
1786 /* Now copy over all the security attributes you have
1787 * parsed out
1788 * */
1789 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1790 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1791 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1792 = RSNEncryptType;
1793 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1794 "EncryptionType = %d mcEncryptionType = %d\n"),
1795 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1796 }
1797 }
1798 }
1799
1800 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1801
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001802#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 if (params->ssid != NULL)
1804 {
1805 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1806 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1807 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1808 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1809 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001810#else
1811 if (ssid != NULL)
1812 {
1813 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1814 pConfig->SSIDinfo.ssid.length = ssid_len;
1815 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1816 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1817 }
1818#endif
1819
Jeff Johnson295189b2012-06-20 16:38:30 -07001820 vos_mem_copy(pConfig->self_macaddr.bytes,
1821 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1822
1823 /* default value */
1824 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1825 pConfig->num_accept_mac = 0;
1826 pConfig->num_deny_mac = 0;
1827
1828 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1829 pBeacon->tail, pBeacon->tail_len);
1830
1831 /* pIe for black list is following form:
1832 type : 1 byte
1833 length : 1 byte
1834 OUI : 4 bytes
1835 acl type : 1 byte
1836 no of mac addr in black list: 1 byte
1837 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1838 */
1839 if ((pIe != NULL) && (pIe[1] != 0))
1840 {
1841 pConfig->SapMacaddr_acl = pIe[6];
1842 pConfig->num_deny_mac = pIe[7];
1843 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1844 pIe[6], pIe[7]);
1845 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1846 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1847 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1848 for (i = 0; i < pConfig->num_deny_mac; i++)
1849 {
1850 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1851 acl_entry++;
1852 }
1853 }
1854 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1855 pBeacon->tail, pBeacon->tail_len);
1856
1857 /* pIe for white list is following form:
1858 type : 1 byte
1859 length : 1 byte
1860 OUI : 4 bytes
1861 acl type : 1 byte
1862 no of mac addr in white list: 1 byte
1863 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1864 */
1865 if ((pIe != NULL) && (pIe[1] != 0))
1866 {
1867 pConfig->SapMacaddr_acl = pIe[6];
1868 pConfig->num_accept_mac = pIe[7];
1869 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1870 pIe[6], pIe[7]);
1871 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1872 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1873 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1874 for (i = 0; i < pConfig->num_accept_mac; i++)
1875 {
1876 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1877 acl_entry++;
1878 }
1879 }
1880 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1881
Jeff Johnsone7245742012-09-05 17:12:55 -07001882#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001883 /* Overwrite the hostapd setting for HW mode only for 11ac.
1884 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1885 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1886 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1887 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1888 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1889 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1890 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001891 {
1892 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1893 }
1894#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301895
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001896 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1897 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001898 // ht_capab is not what the name conveys,this is used for protection bitmap
1899 pConfig->ht_capab =
1900 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1901
1902 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1903 {
1904 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1905 return -EINVAL;
1906 }
1907
1908 //Uapsd Enabled Bit
1909 pConfig->UapsdEnable =
1910 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1911 //Enable OBSS protection
1912 pConfig->obssProtEnabled =
1913 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1914
1915 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1916 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1917 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1918 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1919 (int)pConfig->channel);
1920 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1921 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1922 pConfig->authType);
1923 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1924 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1925 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1926 pConfig->protEnabled, pConfig->obssProtEnabled);
1927
1928 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1929 {
1930 //Bss already started. just return.
1931 //TODO Probably it should update some beacon params.
1932 hddLog( LOGE, "Bss Already started...Ignore the request");
1933 EXIT();
1934 return 0;
1935 }
1936
1937 pConfig->persona = pHostapdAdapter->device_mode;
1938
1939 pSapEventCallback = hdd_hostapd_SAPEventCB;
1940 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1941 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1942 {
1943 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1944 return -EINVAL;
1945 }
1946
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001947 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001948 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1949
1950 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1951
1952 if (!VOS_IS_STATUS_SUCCESS(status))
1953 {
1954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1955 ("ERROR: HDD vos wait for single_event failed!!\n"));
1956 VOS_ASSERT(0);
1957 }
1958
1959 //Succesfully started Bss update the state bit.
1960 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1961
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001962#ifdef WLAN_FEATURE_P2P_DEBUG
1963 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1964 {
1965 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1966 {
1967 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1968 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001969 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001970 }
1971 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1972 {
1973 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1974 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001975 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001976 }
1977 }
1978#endif
1979
Jeff Johnson295189b2012-06-20 16:38:30 -07001980 pHostapdState->bCommit = TRUE;
1981 EXIT();
1982
1983 return 0;
1984}
1985
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001986#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001987static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1988 struct net_device *dev,
1989 struct beacon_parameters *params)
1990{
1991 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1992 int status=VOS_STATUS_SUCCESS;
1993
1994 ENTER();
1995
1996 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1997
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001998 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1999 {
2000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2001 "%s:LOGP in Progress. Ignore!!!", __func__);
2002 return -EAGAIN;
2003 }
2004
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2006#ifdef WLAN_FEATURE_P2P
2007 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2008#endif
2009 )
2010 {
2011 beacon_data_t *old,*new;
2012
2013 old = pAdapter->sessionCtx.ap.beacon;
2014
2015 if (old)
2016 return -EALREADY;
2017
2018 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2019
2020 if(status != VOS_STATUS_SUCCESS)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s:Error!!! Allocating the new beacon\n",__func__);
2024 return -EINVAL;
2025 }
2026
2027 pAdapter->sessionCtx.ap.beacon = new;
2028
2029 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2030 }
2031
2032 EXIT();
2033 return status;
2034}
2035
2036static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
2037 struct net_device *dev,
2038 struct beacon_parameters *params)
2039{
2040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2041 int status=VOS_STATUS_SUCCESS;
2042
2043 ENTER();
2044
2045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2046 __func__,pAdapter->device_mode);
2047
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002048 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2049 {
2050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2051 "%s:LOGP in Progress. Ignore!!!", __func__);
2052 return -EAGAIN;
2053 }
2054
Jeff Johnson295189b2012-06-20 16:38:30 -07002055 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2056#ifdef WLAN_FEATURE_P2P
2057 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2058#endif
2059 )
2060 {
2061 beacon_data_t *old,*new;
2062
2063 old = pAdapter->sessionCtx.ap.beacon;
2064
2065 if (!old)
2066 return -ENOENT;
2067
2068 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2069
2070 if(status != VOS_STATUS_SUCCESS) {
2071 hddLog(VOS_TRACE_LEVEL_FATAL,
2072 "%s: Error!!! Allocating the new beacon\n",__func__);
2073 return -EINVAL;
2074 }
2075
2076 pAdapter->sessionCtx.ap.beacon = new;
2077
2078 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2079 }
2080
2081 EXIT();
2082 return status;
2083}
2084
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002085#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2086
2087#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002088static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2089 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002090#else
2091static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2092 struct net_device *dev)
2093#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002094{
2095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002096 hdd_context_t *pHddCtx = NULL;
2097 hdd_scaninfo_t *pScanInfo = NULL;
2098 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 VOS_STATUS status = 0;
2100
2101 ENTER();
2102
2103 if (NULL == pAdapter)
2104 {
2105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002106 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 return -ENODEV;
2108 }
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002109 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2110 {
2111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2112 "%s:LOGP in Progress. Ignore!!!", __func__);
2113 return -EAGAIN;
2114 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002115
2116 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2117 if (NULL == pHddCtx)
2118 {
2119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002120 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002121 return -ENODEV;
2122 }
2123
2124 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2125 if (NULL == staAdapter)
2126 {
2127 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2128 if (NULL == staAdapter)
2129 {
2130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002131 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002132 return -ENODEV;
2133 }
2134 }
2135
2136 pScanInfo = &pHddCtx->scan_info;
2137
Jeff Johnson295189b2012-06-20 16:38:30 -07002138 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2139 {
2140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2141 return -EAGAIN;
2142 }
2143
2144 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2145
2146 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2147 __func__,pAdapter->device_mode);
2148
Jeff Johnsone7245742012-09-05 17:12:55 -07002149 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2150 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002151 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002152 hdd_abort_mac_scan(staAdapter->pHddCtx);
2153 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002154 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002155 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2156 if (!status)
2157 {
2158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002159 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002160 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002161 VOS_ASSERT(pScanInfo->mScanPending);
2162 return 0;
2163 }
2164 }
2165
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2167#ifdef WLAN_FEATURE_P2P
2168 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2169#endif
2170 )
2171 {
2172 beacon_data_t *old;
2173
2174 old = pAdapter->sessionCtx.ap.beacon;
2175
2176 if (!old)
2177 return -ENOENT;
2178
2179#ifdef CONFIG_CFG80211
2180 hdd_cleanup_actionframe(pHddCtx, pAdapter);
2181#endif
2182
2183 mutex_lock(&pHddCtx->sap_lock);
2184 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2185 {
2186 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pAdapter))->pvosContext) ) )
2187 {
2188 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2189
2190 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2191
2192 if (!VOS_IS_STATUS_SUCCESS(status))
2193 {
2194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2195 ("ERROR: HDD vos wait for single_event failed!!\n"));
2196 VOS_ASSERT(0);
2197 }
2198 }
2199 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2200 }
2201 mutex_unlock(&pHddCtx->sap_lock);
2202
2203 if(status != VOS_STATUS_SUCCESS)
2204 {
2205 hddLog(VOS_TRACE_LEVEL_FATAL,
2206 "%s:Error!!! Stopping the BSS\n",__func__);
2207 return -EINVAL;
2208 }
2209
2210 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2211 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2212 ==eHAL_STATUS_FAILURE)
2213 {
2214 hddLog(LOGE,
2215 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2216 }
2217
2218 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
2219 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2220 eANI_BOOLEAN_FALSE) )
2221 {
2222 hddLog(LOGE,
2223 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2224 }
2225
2226 // Reset WNI_CFG_PROBE_RSP Flags
2227 wlan_hdd_reset_prob_rspies(pAdapter);
2228
2229 pAdapter->sessionCtx.ap.beacon = NULL;
2230 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002231#ifdef WLAN_FEATURE_P2P_DEBUG
2232 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2233 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2234 {
2235 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2236 "GO got removed");
2237 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2238 }
2239#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002240 }
2241 EXIT();
2242 return status;
2243}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002244
2245#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2246
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302247static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2248 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002249 struct cfg80211_ap_settings *params)
2250{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302251 hdd_adapter_t *pAdapter;
2252 hdd_context_t *pHddCtx;
2253 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002254
2255 ENTER();
2256
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302257 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002258 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2260 "%s: Device is Null", __func__);
2261 return -ENODEV;
2262 }
2263
2264 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2265 if (NULL == pAdapter)
2266 {
2267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2268 "%s: HDD adapter is Null", __func__);
2269 return -ENODEV;
2270 }
2271
2272 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2273 {
2274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2275 "%s: HDD adapter magic is invalid", __func__);
2276 return -ENODEV;
2277 }
2278
2279 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2280 if (NULL == pHddCtx)
2281 {
2282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2283 "%s: HDD context is Null", __func__);
2284 return -ENODEV;
2285 }
2286
2287 if (pHddCtx->isLogpInProgress)
2288 {
2289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2290 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002291 return -EAGAIN;
2292 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302293
2294 if (pHddCtx->isLoadUnloadInProgress)
2295 {
2296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2297 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2298 return -EAGAIN;
2299 }
2300
2301 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2302 __func__, pAdapter->device_mode);
2303
2304 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002305#ifdef WLAN_FEATURE_P2P
2306 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2307#endif
2308 )
2309 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302310 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002311
2312 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302313
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002314 if (old)
2315 return -EALREADY;
2316
2317 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2318
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302319 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002320 {
2321 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302322 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002323 return -EINVAL;
2324 }
2325 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002326#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2327 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2328#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002329 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2330 params->ssid_len, params->hidden_ssid);
2331 }
2332
2333 EXIT();
2334 return status;
2335}
2336
2337
2338static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2339 struct net_device *dev,
2340 struct cfg80211_beacon_data *params)
2341{
2342 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2343 int status=VOS_STATUS_SUCCESS;
2344
2345 ENTER();
2346
2347 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2348 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002349 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2350 {
2351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2352 return -EAGAIN;
2353 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002354
2355 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2356#ifdef WLAN_FEATURE_P2P
2357 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2358#endif
2359 )
2360 {
2361 beacon_data_t *old,*new;
2362
2363 old = pAdapter->sessionCtx.ap.beacon;
2364
2365 if (!old)
2366 return -ENOENT;
2367
2368 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2369
2370 if(status != VOS_STATUS_SUCCESS) {
2371 hddLog(VOS_TRACE_LEVEL_FATAL,
2372 "%s: Error!!! Allocating the new beacon\n",__func__);
2373 return -EINVAL;
2374 }
2375
2376 pAdapter->sessionCtx.ap.beacon = new;
2377
2378 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2379 }
2380
2381 EXIT();
2382 return status;
2383}
2384
2385#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2386
Jeff Johnson295189b2012-06-20 16:38:30 -07002387
2388static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2389 struct net_device *dev,
2390 struct bss_parameters *params)
2391{
2392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2393
2394 ENTER();
2395
2396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2397 __func__,pAdapter->device_mode);
2398
2399 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2400#ifdef WLAN_FEATURE_P2P
2401 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2402#endif
2403 )
2404 {
2405 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2406 * want to update this parameter */
2407 if (-1 != params->ap_isolate)
2408 {
2409 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2410 }
2411 }
2412
2413 EXIT();
2414 return 0;
2415}
2416
2417/*
2418 * FUNCTION: wlan_hdd_cfg80211_change_iface
2419 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2420 */
2421int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2422 struct net_device *ndev,
2423 enum nl80211_iftype type,
2424 u32 *flags,
2425 struct vif_params *params
2426 )
2427{
2428 struct wireless_dev *wdev;
2429 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2430 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002431 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002432 tCsrRoamProfile *pRoamProfile = NULL;
2433 eCsrRoamBssType LastBSSType;
2434 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2435 eMib_dot11DesiredBssType connectedBssType;
2436 VOS_STATUS status;
2437
2438 ENTER();
2439
2440 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2441 {
2442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2443 return -EAGAIN;
2444 }
2445
2446 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2447 __func__, pAdapter->device_mode);
2448
2449 wdev = ndev->ieee80211_ptr;
2450
2451#ifdef WLAN_BTAMP_FEATURE
2452 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2453 (NL80211_IFTYPE_ADHOC == type)||
2454 (NL80211_IFTYPE_AP == type)||
2455 (NL80211_IFTYPE_P2P_GO == type))
2456 {
2457 pHddCtx->isAmpAllowed = VOS_FALSE;
2458 // stop AMP traffic
2459 status = WLANBAP_StopAmp();
2460 if(VOS_STATUS_SUCCESS != status )
2461 {
2462 pHddCtx->isAmpAllowed = VOS_TRUE;
2463 hddLog(VOS_TRACE_LEVEL_FATAL,
2464 "%s: Failed to stop AMP", __func__);
2465 return -EINVAL;
2466 }
2467 }
2468#endif //WLAN_BTAMP_FEATURE
2469 /* Reset the current device mode bit mask*/
2470 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2471
2472 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2473#ifdef WLAN_FEATURE_P2P
2474 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002475 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002476#endif
2477 )
2478 {
2479 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2480 pRoamProfile = &pWextState->roamProfile;
2481 LastBSSType = pRoamProfile->BSSType;
2482
2483 switch (type)
2484 {
2485 case NL80211_IFTYPE_STATION:
2486#ifdef WLAN_FEATURE_P2P
2487 case NL80211_IFTYPE_P2P_CLIENT:
2488#endif
2489 hddLog(VOS_TRACE_LEVEL_INFO,
2490 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2491 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002492#ifdef WLAN_FEATURE_11AC
2493 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2494 {
2495 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2496 }
2497#endif
2498 pRoamProfile->phyMode =
2499 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002500 wdev->iftype = type;
2501#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002502 //Check for sub-string p2p to confirm its a p2p interface
2503 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002504 {
2505 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2506 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2507 }
2508 else
2509 {
2510 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002512 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002513#endif
2514 break;
2515 case NL80211_IFTYPE_ADHOC:
2516 hddLog(VOS_TRACE_LEVEL_INFO,
2517 "%s: setting interface Type to ADHOC", __func__);
2518 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2519 pRoamProfile->phyMode =
2520 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2521 wdev->iftype = type;
2522 break;
2523
2524 case NL80211_IFTYPE_AP:
2525#ifdef WLAN_FEATURE_P2P
2526 case NL80211_IFTYPE_P2P_GO:
2527#endif
2528 {
2529 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2530 "%s: setting interface Type to %s", __func__,
2531 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2532
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002533 //Cancel any remain on channel for GO mode
2534 if (NL80211_IFTYPE_P2P_GO == type)
2535 {
2536 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2537 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002538 if (NL80211_IFTYPE_AP == type)
2539 {
2540 /* As Loading WLAN Driver one interface being created for p2p device
2541 * address. This will take one HW STA and the max number of clients
2542 * that can connect to softAP will be reduced by one. so while changing
2543 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2544 * interface as it is not required in SoftAP mode.
2545 */
2546
2547 // Get P2P Adapter
2548 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2549
2550 if (pP2pAdapter)
2551 {
2552 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2553 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2554 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2555 }
2556 }
2557
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 //De-init the adapter.
2559 hdd_stop_adapter( pHddCtx, pAdapter );
2560 hdd_deinit_adapter( pHddCtx, pAdapter );
2561 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2562#ifdef WLAN_SOFTAP_FEATURE
2563#ifdef WLAN_FEATURE_P2P
2564 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2565 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2566#else
2567 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2568#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002569
2570 //Disable BMPS and IMPS if enabled
2571 //before starting Go
2572 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2573 {
2574 if(VOS_STATUS_E_FAILURE ==
2575 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2576 {
2577 //Fail to Exit BMPS
2578 VOS_ASSERT(0);
2579 }
2580 }
2581
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002582 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2583 (pConfig->apRandomBssidEnabled))
2584 {
2585 /* To meet Android requirements create a randomized
2586 MAC address of the form 02:1A:11:Fx:xx:xx */
2587 get_random_bytes(&ndev->dev_addr[3], 3);
2588 ndev->dev_addr[0] = 0x02;
2589 ndev->dev_addr[1] = 0x1A;
2590 ndev->dev_addr[2] = 0x11;
2591 ndev->dev_addr[3] |= 0xF0;
2592 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2593 VOS_MAC_ADDR_SIZE);
2594 pr_info("wlan: Generated HotSpot BSSID "
2595 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2596 ndev->dev_addr[0],
2597 ndev->dev_addr[1],
2598 ndev->dev_addr[2],
2599 ndev->dev_addr[3],
2600 ndev->dev_addr[4],
2601 ndev->dev_addr[5]);
2602 }
2603
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 hdd_set_ap_ops( pAdapter->dev );
2605
2606 status = hdd_init_ap_mode(pAdapter);
2607 if(status != VOS_STATUS_SUCCESS)
2608 {
2609 hddLog(VOS_TRACE_LEVEL_FATAL,
2610 "%s: Error initializing the ap mode", __func__);
2611 return -EINVAL;
2612 }
2613 hdd_set_conparam(1);
2614
2615#endif
2616 /*interface type changed update in wiphy structure*/
2617 if(wdev)
2618 {
2619 wdev->iftype = type;
2620 pHddCtx->change_iface = type;
2621 }
2622 else
2623 {
2624 hddLog(VOS_TRACE_LEVEL_ERROR,
2625 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2626 return -EINVAL;
2627 }
2628 goto done;
2629 }
2630
2631 default:
2632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2633 __func__);
2634 return -EOPNOTSUPP;
2635 }
2636 }
2637 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2638#ifdef WLAN_FEATURE_P2P
2639 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2640#endif
2641 )
2642 {
2643 switch(type)
2644 {
2645 case NL80211_IFTYPE_STATION:
2646#ifdef WLAN_FEATURE_P2P
2647 case NL80211_IFTYPE_P2P_CLIENT:
2648#endif
2649 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002650 hdd_stop_adapter( pHddCtx, pAdapter );
2651 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002652 wdev->iftype = type;
2653#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002654 //Check for sub-string p2p to confirm its a p2p interface
2655 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002656 {
2657 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2658 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2659 }
2660 else
2661 {
2662 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002663 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002665#endif
2666 hdd_set_conparam(0);
2667 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2669 hdd_set_station_ops( pAdapter->dev );
2670 status = hdd_init_station_mode( pAdapter );
2671 if( VOS_STATUS_SUCCESS != status )
2672 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002673 /* In case of JB, for P2P-GO, only change interface will be called,
2674 * This is the right place to enable back bmps_imps()
2675 */
2676 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002677 goto done;
2678 case NL80211_IFTYPE_AP:
2679#ifdef WLAN_FEATURE_P2P
2680 case NL80211_IFTYPE_P2P_GO:
2681#endif
2682 wdev->iftype = type;
2683#ifdef WLAN_FEATURE_P2P
2684 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2685 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2686#endif
2687 goto done;
2688 default:
2689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2690 __func__);
2691 return -EOPNOTSUPP;
2692
2693 }
2694
2695 }
2696 else
2697 {
2698 return -EOPNOTSUPP;
2699 }
2700
2701
2702 if(pRoamProfile)
2703 {
2704 if ( LastBSSType != pRoamProfile->BSSType )
2705 {
2706 /*interface type changed update in wiphy structure*/
2707 wdev->iftype = type;
2708
2709 /*the BSS mode changed, We need to issue disconnect
2710 if connected or in IBSS disconnect state*/
2711 if ( hdd_connGetConnectedBssType(
2712 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2713 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2714 {
2715 /*need to issue a disconnect to CSR.*/
2716 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2717 if( eHAL_STATUS_SUCCESS ==
2718 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2719 pAdapter->sessionId,
2720 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2721 {
2722 wait_for_completion_interruptible_timeout(
2723 &pAdapter->disconnect_comp_var,
2724 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2725 }
2726 }
2727 }
2728 }
2729
2730done:
2731 /*set bitmask based on updated value*/
2732 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2733#ifdef WLAN_BTAMP_FEATURE
2734 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2735 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2736 {
2737 //we are ok to do AMP
2738 pHddCtx->isAmpAllowed = VOS_TRUE;
2739 }
2740#endif //WLAN_BTAMP_FEATURE
2741 EXIT();
2742 return 0;
2743}
2744
2745static int wlan_hdd_change_station(struct wiphy *wiphy,
2746 struct net_device *dev,
2747 u8 *mac,
2748 struct station_parameters *params)
2749{
2750 VOS_STATUS status = VOS_STATUS_SUCCESS;
2751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2752 v_MACADDR_t STAMacAddress;
2753
Jeff Johnsone7245742012-09-05 17:12:55 -07002754 ENTER();
2755
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002756 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2757 {
2758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2759 "%s:LOGP in Progress. Ignore!!!", __func__);
2760 return -EAGAIN;
2761 }
2762
Jeff Johnson295189b2012-06-20 16:38:30 -07002763 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2764
2765 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2766#ifdef WLAN_FEATURE_P2P
2767 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2768#endif
2769 )
2770 {
2771 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2772 {
2773 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2774 WLANTL_STA_AUTHENTICATED);
2775
2776 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002777 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002778 return -EINVAL;
2779 }
2780 }
2781
Jeff Johnsone7245742012-09-05 17:12:55 -07002782 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002783 return status;
2784}
2785
2786/*
2787 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2788 * This function is used to get peer station index in IBSS mode
2789 */
2790static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2791{
2792 u8 idx = 0;
2793 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2794 ENTER();
2795 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2796 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2797 {
2798 if ( (0 !=
2799 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2800 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2801 temp, VOS_MAC_ADDR_SIZE)
2802 )
2803 {
2804 return idx;
2805 }
2806 }
2807 return idx;
2808}
2809
2810
2811/*
2812 * FUNCTION: wlan_hdd_cfg80211_add_key
2813 * This function is used to initialize the key information
2814 */
2815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2816static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2817 struct net_device *ndev,
2818 u8 key_index, bool pairwise,
2819 const u8 *mac_addr,
2820 struct key_params *params
2821 )
2822#else
2823static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2824 struct net_device *ndev,
2825 u8 key_index, const u8 *mac_addr,
2826 struct key_params *params
2827 )
2828#endif
2829{
2830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2831 tCsrRoamSetKey setKey;
2832 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2833 int status = 0;
2834 v_U32_t roamId= 0xFF;
2835 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2836 hdd_hostapd_state_t *pHostapdState;
2837 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002838 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002839
2840 ENTER();
2841
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002842 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2843 {
2844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2845 "%s:LOGP in Progress. Ignore!!!", __func__);
2846 return -EAGAIN;
2847 }
2848
Jeff Johnson295189b2012-06-20 16:38:30 -07002849 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2850 __func__,pAdapter->device_mode);
2851
2852 if (CSR_MAX_NUM_KEY <= key_index)
2853 {
2854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2855 key_index);
2856
2857 return -EINVAL;
2858 }
2859
2860 hddLog(VOS_TRACE_LEVEL_INFO,
2861 "%s: called with key index = %d & key length %d",
2862 __func__, key_index, params->key_len);
2863
2864 /*extract key idx, key len and key*/
2865 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2866 setKey.keyId = key_index;
2867 setKey.keyLength = params->key_len;
2868 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2869
2870 switch (params->cipher)
2871 {
2872 case WLAN_CIPHER_SUITE_WEP40:
2873 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2874 break;
2875
2876 case WLAN_CIPHER_SUITE_WEP104:
2877 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2878 break;
2879
2880 case WLAN_CIPHER_SUITE_TKIP:
2881 {
2882 u8 *pKey = &setKey.Key[0];
2883 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2884
2885 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2886
2887 /*Supplicant sends the 32bytes key in this order
2888
2889 |--------------|----------|----------|
2890 | Tk1 |TX-MIC | RX Mic |
2891 |--------------|----------|----------|
2892 <---16bytes---><--8bytes--><--8bytes-->
2893
2894 */
2895 /*Sme expects the 32 bytes key to be in the below order
2896
2897 |--------------|----------|----------|
2898 | Tk1 |RX-MIC | TX Mic |
2899 |--------------|----------|----------|
2900 <---16bytes---><--8bytes--><--8bytes-->
2901 */
2902 /* Copy the Temporal Key 1 (TK1) */
2903 vos_mem_copy(pKey, params->key,16);
2904
2905 /*Copy the rx mic first*/
2906 vos_mem_copy(&pKey[16],&params->key[24],8);
2907
2908 /*Copy the tx mic */
2909 vos_mem_copy(&pKey[24],&params->key[16],8);
2910
2911
2912 break;
2913 }
2914
2915 case WLAN_CIPHER_SUITE_CCMP:
2916 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2917 break;
2918
2919#ifdef FEATURE_WLAN_WAPI
2920 case WLAN_CIPHER_SUITE_SMS4:
2921 {
2922 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2923 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2924 params->key, params->key_len);
2925 return 0;
2926 }
2927#endif
2928#ifdef FEATURE_WLAN_CCX
2929 case WLAN_CIPHER_SUITE_KRK:
2930 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2931 break;
2932#endif
2933 default:
2934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2935 __func__, params->cipher);
2936 return -EOPNOTSUPP;
2937 }
2938
2939 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2940 __func__, setKey.encType);
2941
2942
2943
2944 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2945#ifdef WLAN_FEATURE_P2P
2946 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2947#endif
2948 )
2949 {
2950
2951
2952 if (
2953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2954 (!pairwise)
2955#else
2956 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2957#endif
2958 )
2959 {
2960 /* set group key*/
2961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08002962 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002963 __func__, __LINE__);
2964 setKey.keyDirection = eSIR_RX_ONLY;
2965 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2966 }
2967 else
2968 {
2969 /* set pairwise key*/
2970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2971 "%s- %d: setting pairwise key",
2972 __func__, __LINE__);
2973 setKey.keyDirection = eSIR_TX_RX;
2974 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2975 }
2976
2977 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2978 if( pHostapdState->bssState == BSS_START )
2979 {
2980 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2981
2982 if ( status != eHAL_STATUS_SUCCESS )
2983 {
2984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2985 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2986 __LINE__, status );
2987 }
2988 }
2989
2990 /* Saving WEP keys */
2991 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2992 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2993 {
2994 //Save the wep key in ap context. Issue setkey after the BSS is started.
2995 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2996 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2997 }
2998 else
2999 {
3000 //Save the key in ap context. Issue setkey after the BSS is started.
3001 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3002 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3003 }
3004 }
3005 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3006#ifdef WLAN_FEATURE_P2P
3007 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3008#endif
3009 )
3010 {
3011 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3012 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3013
3014 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3015
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003016 pWextState->roamProfile.Keys.defaultIndex = key_index;
3017
3018
Jeff Johnson295189b2012-06-20 16:38:30 -07003019 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3020 params->key, params->key_len);
3021
3022 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3023
3024 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3025 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3026 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3027 )
3028 &&
3029 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3030 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3031 )
3032 )
3033 {
3034 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3035 * interface, copy bssid for pairwise key and group macaddr for
3036 * group key initialization*/
3037
3038 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3039
3040 pWextState->roamProfile.negotiatedUCEncryptionType =
3041 pHddStaCtx->conn_info.ucEncryptionType =
3042 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3043 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3044 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3045
3046
3047 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3048 "%s: Negotiated encryption type %d", __func__,
3049 pWextState->roamProfile.negotiatedUCEncryptionType);
3050
3051 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3052 &pWextState->roamProfile, true);
3053 setKey.keyLength = 0;
3054 setKey.keyDirection = eSIR_TX_RX;
3055
3056#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3057 if (pairwise)
3058 {
3059#endif
3060 if (mac_addr)
3061 {
3062 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3063 }
3064 else
3065 {
3066 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3067 * and peerMacAddress in case of IBSS*/
3068 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3069 {
3070 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3071 if (HDD_MAX_NUM_IBSS_STA != staidx)
3072 {
3073 vos_mem_copy(setKey.peerMac,
3074 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3075 WNI_CFG_BSSID_LEN);
3076
3077 }
3078 else
3079 {
3080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3081 __func__);
3082 return -EOPNOTSUPP;
3083 }
3084 }
3085 else
3086 {
3087 vos_mem_copy(setKey.peerMac,
3088 &pHddStaCtx->conn_info.bssId[0],
3089 WNI_CFG_BSSID_LEN);
3090 }
3091 }
3092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3093 }
3094 else
3095 {
3096 /* set group key*/
3097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3098 "%s- %d: setting Group key",
3099 __func__, __LINE__);
3100 setKey.keyDirection = eSIR_RX_ONLY;
3101 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3102 }
3103#endif
3104 }
3105 else if (
3106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3107 (!pairwise)
3108#else
3109 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3110#endif
3111 )
3112 {
3113 /* set group key*/
3114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3115 "%s- %d: setting Group key",
3116 __func__, __LINE__);
3117 setKey.keyDirection = eSIR_RX_ONLY;
3118 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3119 }
3120 else
3121 {
3122 /* set pairwise key*/
3123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3124 "%s- %d: setting pairwise key",
3125 __func__, __LINE__);
3126 setKey.keyDirection = eSIR_TX_RX;
3127 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3128 }
3129
3130 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3131 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3132 __func__, setKey.peerMac[0], setKey.peerMac[1],
3133 setKey.peerMac[2], setKey.peerMac[3],
3134 setKey.peerMac[4], setKey.peerMac[5],
3135 setKey.keyDirection);
3136
3137 vos_status = wlan_hdd_check_ula_done(pAdapter);
3138
3139 if ( vos_status != VOS_STATUS_SUCCESS )
3140 {
3141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3142 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3143 __LINE__, vos_status );
3144
3145 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3146
3147 return -EINVAL;
3148
3149 }
3150
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003151#ifdef WLAN_FEATURE_VOWIFI_11R
3152 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3153 Save the key in the UMAC and include it in the ADD BSS request */
3154 /*TODO 11r - is this used?? */
3155 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
3156 if( halStatus == eHAL_STATUS_SUCCESS )
3157 {
3158 return halStatus;
3159 }
3160#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003161
3162 /* issue set key request to SME*/
3163 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3164 pAdapter->sessionId, &setKey, &roamId );
3165
3166 if ( 0 != status )
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR,
3169 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3170 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3171 return -EINVAL;
3172 }
3173
3174
3175 /* in case of IBSS as there was no information available about WEP keys during
3176 * IBSS join, group key intialized with NULL key, so re-initialize group key
3177 * with correct value*/
3178 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3179 !( ( IW_AUTH_KEY_MGMT_802_1X
3180 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3181 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3182 )
3183 &&
3184 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3185 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3186 )
3187 )
3188 {
3189 setKey.keyDirection = eSIR_RX_ONLY;
3190 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3191
3192 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3193 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3194 __func__, setKey.peerMac[0], setKey.peerMac[1],
3195 setKey.peerMac[2], setKey.peerMac[3],
3196 setKey.peerMac[4], setKey.peerMac[5],
3197 setKey.keyDirection);
3198
3199 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3200 pAdapter->sessionId, &setKey, &roamId );
3201
3202 if ( 0 != status )
3203 {
3204 hddLog(VOS_TRACE_LEVEL_ERROR,
3205 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3206 __func__, status);
3207 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3208 return -EINVAL;
3209 }
3210 }
3211 }
3212
3213 return 0;
3214}
3215
3216/*
3217 * FUNCTION: wlan_hdd_cfg80211_get_key
3218 * This function is used to get the key information
3219 */
3220#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3221static int wlan_hdd_cfg80211_get_key(
3222 struct wiphy *wiphy,
3223 struct net_device *ndev,
3224 u8 key_index, bool pairwise,
3225 const u8 *mac_addr, void *cookie,
3226 void (*callback)(void *cookie, struct key_params*)
3227 )
3228#else
3229static int wlan_hdd_cfg80211_get_key(
3230 struct wiphy *wiphy,
3231 struct net_device *ndev,
3232 u8 key_index, const u8 *mac_addr, void *cookie,
3233 void (*callback)(void *cookie, struct key_params*)
3234 )
3235#endif
3236{
3237 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3238 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3239 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3240 struct key_params params;
3241
3242 ENTER();
3243
3244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3245 __func__,pAdapter->device_mode);
3246
3247 memset(&params, 0, sizeof(params));
3248
3249 if (CSR_MAX_NUM_KEY <= key_index)
3250 {
3251 return -EINVAL;
3252 }
3253
3254 switch(pRoamProfile->EncryptionType.encryptionType[0])
3255 {
3256 case eCSR_ENCRYPT_TYPE_NONE:
3257 params.cipher = IW_AUTH_CIPHER_NONE;
3258 break;
3259
3260 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3261 case eCSR_ENCRYPT_TYPE_WEP40:
3262 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3263 break;
3264
3265 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3266 case eCSR_ENCRYPT_TYPE_WEP104:
3267 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3268 break;
3269
3270 case eCSR_ENCRYPT_TYPE_TKIP:
3271 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3272 break;
3273
3274 case eCSR_ENCRYPT_TYPE_AES:
3275 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3276 break;
3277
3278 default:
3279 params.cipher = IW_AUTH_CIPHER_NONE;
3280 break;
3281 }
3282
3283 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3284 params.seq_len = 0;
3285 params.seq = NULL;
3286 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3287 callback(cookie, &params);
3288 return 0;
3289}
3290
3291/*
3292 * FUNCTION: wlan_hdd_cfg80211_del_key
3293 * This function is used to delete the key information
3294 */
3295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3296static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3297 struct net_device *ndev,
3298 u8 key_index,
3299 bool pairwise,
3300 const u8 *mac_addr
3301 )
3302#else
3303static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3304 struct net_device *ndev,
3305 u8 key_index,
3306 const u8 *mac_addr
3307 )
3308#endif
3309{
3310 int status = 0;
3311
3312 //This code needs to be revisited. There is sme_removeKey API, we should
3313 //plan to use that. After the change to use correct index in setkey,
3314 //it is observed that this is invalidating peer
3315 //key index whenever re-key is done. This is affecting data link.
3316 //It should be ok to ignore del_key.
3317#if 0
3318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3319 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3320 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3321 tCsrRoamSetKey setKey;
3322 v_U32_t roamId= 0xFF;
3323
3324 ENTER();
3325
3326 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3327 __func__,pAdapter->device_mode);
3328
3329 if (CSR_MAX_NUM_KEY <= key_index)
3330 {
3331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3332 key_index);
3333
3334 return -EINVAL;
3335 }
3336
3337 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3338 setKey.keyId = key_index;
3339
3340 if (mac_addr)
3341 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3342 else
3343 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3344
3345 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3346
3347 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3348#ifdef WLAN_FEATURE_P2P
3349 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3350#endif
3351 )
3352 {
3353
3354 hdd_hostapd_state_t *pHostapdState =
3355 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3356 if( pHostapdState->bssState == BSS_START)
3357 {
3358 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3359
3360 if ( status != eHAL_STATUS_SUCCESS )
3361 {
3362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3363 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3364 __LINE__, status );
3365 }
3366 }
3367 }
3368 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3369#ifdef WLAN_FEATURE_P2P
3370 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3371#endif
3372 )
3373 {
3374 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3375
3376 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3377
3378 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3379 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3380 __func__, setKey.peerMac[0], setKey.peerMac[1],
3381 setKey.peerMac[2], setKey.peerMac[3],
3382 setKey.peerMac[4], setKey.peerMac[5]);
3383 if(pAdapter->sessionCtx.station.conn_info.connState ==
3384 eConnectionState_Associated)
3385 {
3386 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3387 pAdapter->sessionId, &setKey, &roamId );
3388
3389 if ( 0 != status )
3390 {
3391 hddLog(VOS_TRACE_LEVEL_ERROR,
3392 "%s: sme_RoamSetKey failure, returned %d",
3393 __func__, status);
3394 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3395 return -EINVAL;
3396 }
3397 }
3398 }
3399#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003400 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003401 return status;
3402}
3403
3404/*
3405 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3406 * This function is used to set the default tx key index
3407 */
3408#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3409static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3410 struct net_device *ndev,
3411 u8 key_index,
3412 bool unicast, bool multicast)
3413#else
3414static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3415 struct net_device *ndev,
3416 u8 key_index)
3417#endif
3418{
3419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3420 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3421 int status = 0;
3422 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3423
3424 ENTER();
3425
3426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3427 __func__,pAdapter->device_mode, key_index);
3428
3429 if (CSR_MAX_NUM_KEY <= key_index)
3430 {
3431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3432 key_index);
3433
3434 return -EINVAL;
3435 }
3436
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003437 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3438 {
3439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3440 "%s:LOGP in Progress. Ignore!!!", __func__);
3441 return -EAGAIN;
3442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003443
3444 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3445#ifdef WLAN_FEATURE_P2P
3446 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3447#endif
3448 )
3449 {
3450 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3451 (eCSR_ENCRYPT_TYPE_TKIP !=
3452 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3453 (eCSR_ENCRYPT_TYPE_AES !=
3454 pWextState->roamProfile.EncryptionType.encryptionType[0])
3455 )
3456 {
3457 /* if default key index is not same as previous one,
3458 * then update the default key index */
3459
3460 tCsrRoamSetKey setKey;
3461 v_U32_t roamId= 0xFF;
3462 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3463
3464 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3465 __func__, key_index);
3466
3467 Keys->defaultIndex = (u8)key_index;
3468 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3469 setKey.keyId = key_index;
3470 setKey.keyLength = Keys->KeyLength[key_index];
3471
3472 vos_mem_copy(&setKey.Key[0],
3473 &Keys->KeyMaterial[key_index][0],
3474 Keys->KeyLength[key_index]);
3475
3476 setKey.keyDirection = eSIR_TX_ONLY;
3477
3478 vos_mem_copy(setKey.peerMac,
3479 &pHddStaCtx->conn_info.bssId[0],
3480 WNI_CFG_BSSID_LEN);
3481
3482 setKey.encType =
3483 pWextState->roamProfile.EncryptionType.encryptionType[0];
3484
3485 /* issue set key request */
3486 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3487 pAdapter->sessionId, &setKey, &roamId );
3488
3489 if ( 0 != status )
3490 {
3491 hddLog(VOS_TRACE_LEVEL_ERROR,
3492 "%s: sme_RoamSetKey failed, returned %d", __func__,
3493 status);
3494 return -EINVAL;
3495 }
3496 }
3497 }
3498
3499 /* In SoftAp mode setting key direction for default mode */
3500 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3501 {
3502 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3503 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3504 (eCSR_ENCRYPT_TYPE_AES !=
3505 pWextState->roamProfile.EncryptionType.encryptionType[0])
3506 )
3507 {
3508 /* Saving key direction for default key index to TX default */
3509 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3510 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3511 }
3512 }
3513
3514 return status;
3515}
3516
Jeff Johnson295189b2012-06-20 16:38:30 -07003517/*
3518 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3519 * This function is used to inform the BSS details to nl80211 interface.
3520 */
3521static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3522 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3523{
3524 struct net_device *dev = pAdapter->dev;
3525 struct wireless_dev *wdev = dev->ieee80211_ptr;
3526 struct wiphy *wiphy = wdev->wiphy;
3527 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3528 int chan_no;
3529 int ie_length;
3530 const char *ie;
3531 unsigned int freq;
3532 struct ieee80211_channel *chan;
3533 int rssi = 0;
3534 struct cfg80211_bss *bss = NULL;
3535
3536 ENTER();
3537
3538 if( NULL == pBssDesc )
3539 {
3540 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3541 return bss;
3542 }
3543
3544 chan_no = pBssDesc->channelId;
3545 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3546 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3547
3548 if( NULL == ie )
3549 {
3550 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3551 return bss;
3552 }
3553
3554#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3555 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3556 {
3557 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3558 }
3559 else
3560 {
3561 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3562 }
3563#else
3564 freq = ieee80211_channel_to_frequency(chan_no);
3565#endif
3566
3567 chan = __ieee80211_get_channel(wiphy, freq);
3568
3569 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3570 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3571 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3572 if (bss == NULL)
3573 {
3574 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3575
3576 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3577 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3578 pBssDesc->capabilityInfo,
3579 pBssDesc->beaconInterval, ie, ie_length,
3580 rssi, GFP_KERNEL ));
3581}
3582 else
3583 {
3584 return bss;
3585 }
3586}
3587
3588
3589
3590/*
3591 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3592 * This function is used to inform the BSS details to nl80211 interface.
3593 */
3594struct cfg80211_bss*
3595wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3596 tSirBssDescription *bss_desc
3597 )
3598{
3599 /*
3600 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3601 already exists in bss data base of cfg80211 for that particular BSS ID.
3602 Using cfg80211_inform_bss_frame to update the bss entry instead of
3603 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3604 now there is no possibility to get the mgmt(probe response) frame from PE,
3605 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3606 cfg80211_inform_bss_frame.
3607 */
3608 struct net_device *dev = pAdapter->dev;
3609 struct wireless_dev *wdev = dev->ieee80211_ptr;
3610 struct wiphy *wiphy = wdev->wiphy;
3611 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003612#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3613 qcom_ie_age *qie_age = NULL;
3614 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3615#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003616 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003617#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003618 const char *ie =
3619 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3620 unsigned int freq;
3621 struct ieee80211_channel *chan;
3622 struct ieee80211_mgmt *mgmt =
3623 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3624 struct cfg80211_bss *bss_status = NULL;
3625 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3626 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003627#ifdef WLAN_OPEN_SOURCE
3628 struct timespec ts;
3629#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003630
3631 ENTER();
3632
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003633 if (!mgmt)
3634 return NULL;
3635
Jeff Johnson295189b2012-06-20 16:38:30 -07003636 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003637
3638#ifdef WLAN_OPEN_SOURCE
3639 /* Android does not want the timestamp from the frame.
3640 Instead it wants a monotonic increasing value */
3641 get_monotonic_boottime(&ts);
3642 mgmt->u.probe_resp.timestamp =
3643 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3644#else
3645 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3647 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003648
3649#endif
3650
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3652 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003653
3654#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3655 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3656 /* Assuming this is the last IE, copy at the end */
3657 ie_length -=sizeof(qcom_ie_age);
3658 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3659 qie_age->element_id = QCOM_VENDOR_IE_ID;
3660 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3661 qie_age->oui_1 = QCOM_OUI1;
3662 qie_age->oui_2 = QCOM_OUI2;
3663 qie_age->oui_3 = QCOM_OUI3;
3664 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3665 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3666#endif
3667
Jeff Johnson295189b2012-06-20 16:38:30 -07003668 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3669
3670 mgmt->frame_control |=
3671 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3672
3673#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3674 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3675 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3676 {
3677 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3678 }
3679 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3680 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3681
3682 {
3683 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3684 }
3685 else
3686 {
3687 kfree(mgmt);
3688 return NULL;
3689 }
3690#else
3691 freq = ieee80211_channel_to_frequency(chan_no);
3692#endif
3693 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003694 /*when the band is changed on the fly using the GUI, three things are done
3695 * 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)
3696 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3697 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3698 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3699 * and discards the channels correponding to previous band and calls back with zero bss results.
3700 * 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
3701 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3702 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3703 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3704 * So drop the bss and continue to next bss.
3705 */
3706 if(chan == NULL)
3707 {
3708 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3709 return NULL;
3710 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003711 /*To keep the rssi icon of the connected AP in the scan window
3712 *and the rssi icon of the wireless networks in sync
3713 * */
3714 if (( eConnectionState_Associated ==
3715 pAdapter->sessionCtx.station.conn_info.connState ) &&
3716 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3717 pAdapter->sessionCtx.station.conn_info.bssId,
3718 WNI_CFG_BSSID_LEN)))
3719 {
3720 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3721 rssi = (pAdapter->rssi * 100);
3722 }
3723 else
3724 {
3725 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3726 }
3727
3728 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3729 frame_len, rssi, GFP_KERNEL);
3730 kfree(mgmt);
3731 return bss_status;
3732}
3733
3734/*
3735 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3736 * This function is used to update the BSS data base of CFG8011
3737 */
3738struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3739 tCsrRoamInfo *pRoamInfo
3740 )
3741{
3742 tCsrRoamConnectedProfile roamProfile;
3743 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3744 struct cfg80211_bss *bss = NULL;
3745
3746 ENTER();
3747
3748 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3749 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3750
3751 if (NULL != roamProfile.pBssDesc)
3752 {
3753 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3754 &roamProfile);
3755
3756 if (NULL == bss)
3757 {
3758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3759 __func__);
3760 }
3761
3762 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3763 }
3764 else
3765 {
3766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3767 __func__);
3768 }
3769 return bss;
3770}
3771
3772/*
3773 * FUNCTION: wlan_hdd_cfg80211_update_bss
3774 */
3775static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3776 hdd_adapter_t *pAdapter
3777 )
3778{
3779 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3780 tCsrScanResultInfo *pScanResult;
3781 eHalStatus status = 0;
3782 tScanResultHandle pResult;
3783 struct cfg80211_bss *bss_status = NULL;
3784
3785 ENTER();
3786
3787 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3788 {
3789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3790 return -EAGAIN;
3791 }
3792
3793 /*
3794 * start getting scan results and populate cgf80211 BSS database
3795 */
3796 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3797
3798 /* no scan results */
3799 if (NULL == pResult)
3800 {
3801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3802 return status;
3803 }
3804
3805 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3806
3807 while (pScanResult)
3808 {
3809 /*
3810 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3811 * entry already exists in bss data base of cfg80211 for that
3812 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3813 * bss entry instead of cfg80211_inform_bss, But this call expects
3814 * mgmt packet as input. As of now there is no possibility to get
3815 * the mgmt(probe response) frame from PE, converting bss_desc to
3816 * ieee80211_mgmt(probe response) and passing to c
3817 * fg80211_inform_bss_frame.
3818 * */
3819
3820 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3821 &pScanResult->BssDescriptor);
3822
3823
3824 if (NULL == bss_status)
3825 {
3826 hddLog(VOS_TRACE_LEVEL_INFO,
3827 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3828 }
3829 else
3830 {
3831 cfg80211_put_bss(bss_status);
3832 }
3833
3834 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3835 }
3836
3837 sme_ScanResultPurge(hHal, pResult);
3838
3839 return 0;
3840}
3841
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003842void
3843hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3844{
3845 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003846 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3847 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3848 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003849} /****** end hddPrintMacAddr() ******/
3850
3851void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003852hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003853{
3854 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003855 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3856 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3857 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3858 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003859} /****** end hddPrintPmkId() ******/
3860
3861//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3862//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3863
3864//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3865//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3866
3867#define dump_bssid(bssid) \
3868 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003869 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3870 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3871 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003872 }
3873
3874#define dump_pmkid(pMac, pmkid) \
3875 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003876 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3877 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3878 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003879 }
3880
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003881#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003882/*
3883 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3884 * This function is used to notify the supplicant of a new PMKSA candidate.
3885 */
3886int wlan_hdd_cfg80211_pmksa_candidate_notify(
3887 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3888 int index, bool preauth )
3889{
Jeff Johnsone7245742012-09-05 17:12:55 -07003890#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003891 struct net_device *dev = pAdapter->dev;
3892
3893 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003894 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003895
3896 if( NULL == pRoamInfo )
3897 {
3898 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3899 return -EINVAL;
3900 }
3901
3902 dump_bssid(pRoamInfo->bssid);
3903 cfg80211_pmksa_candidate_notify(dev, index,
3904 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003905#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003906 return 0;
3907}
3908#endif //FEATURE_WLAN_LFR
3909
Jeff Johnson295189b2012-06-20 16:38:30 -07003910/*
3911 * FUNCTION: hdd_cfg80211_scan_done_callback
3912 * scanning callback function, called after finishing scan
3913 *
3914 */
3915static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3916 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3917{
3918 struct net_device *dev = (struct net_device *) pContext;
3919 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3920 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003921 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3922 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003923 struct cfg80211_scan_request *req = NULL;
3924 int ret = 0;
3925
3926 ENTER();
3927
3928 hddLog(VOS_TRACE_LEVEL_INFO,
3929 "%s called with halHandle = %p, pContext = %p,"
3930 "scanID = %d, returned status = %d\n",
3931 __func__, halHandle, pContext, (int) scanId, (int) status);
3932
3933 //Block on scan req completion variable. Can't wait forever though.
3934 ret = wait_for_completion_interruptible_timeout(
3935 &pScanInfo->scan_req_completion_event,
3936 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3937 if (!ret)
3938 {
3939 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003940 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003941 }
3942
3943 if(pScanInfo->mScanPending != VOS_TRUE)
3944 {
3945 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003946 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003947 }
3948
3949 /* Check the scanId */
3950 if (pScanInfo->scanId != scanId)
3951 {
3952 hddLog(VOS_TRACE_LEVEL_INFO,
3953 "%s called with mismatched scanId pScanInfo->scanId = %d "
3954 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3955 (int) scanId);
3956 }
3957
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3959 pAdapter);
3960
3961 if (0 > ret)
3962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3963
3964
3965 /* If any client wait scan result through WEXT
3966 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003967 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 {
3969 /* The other scan request waiting for current scan finish
3970 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003971 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003972 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003973 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003974 }
3975 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003976 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003977 {
3978 struct net_device *dev = pAdapter->dev;
3979 union iwreq_data wrqu;
3980 int we_event;
3981 char *msg;
3982
3983 memset(&wrqu, '\0', sizeof(wrqu));
3984 we_event = SIOCGIWSCAN;
3985 msg = NULL;
3986 wireless_send_event(dev, we_event, &wrqu, msg);
3987 }
3988 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003989 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003990
3991 /* Get the Scan Req */
3992 req = pAdapter->request;
3993
3994 if (!req)
3995 {
3996 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003997 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003998 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003999 }
4000
4001 /*
4002 * setting up 0, just in case.
4003 */
4004 req->n_ssids = 0;
4005 req->n_channels = 0;
4006 req->ie = 0;
4007
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004009 /* Scan is no longer pending */
4010 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004011
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004012 /*
4013 * cfg80211_scan_done informing NL80211 about completion
4014 * of scanning
4015 */
4016 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004017 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004018
Jeff Johnsone7245742012-09-05 17:12:55 -07004019allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004020 /* release the wake lock at the end of the scan*/
4021 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004022
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004023 /* Acquire wakelock to handle the case where APP's tries to suspend
4024 * immediatly after the driver gets connect request(i.e after scan)
4025 * from supplicant, this result in app's is suspending and not able
4026 * to process the connect request to AP */
4027 hdd_allow_suspend_timeout(100);
4028
Jeff Johnson295189b2012-06-20 16:38:30 -07004029 EXIT();
4030 return 0;
4031}
4032
4033/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004034 * FUNCTION: hdd_isScanAllowed
4035 * Go through each adapter and check if scan allowed
4036 *
4037 */
4038v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4039{
4040 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4041 hdd_station_ctx_t *pHddStaCtx = NULL;
4042 hdd_adapter_t *pAdapter = NULL;
4043 VOS_STATUS status = 0;
4044 v_U8_t staId = 0;
4045 v_U8_t *staMac = NULL;
4046
4047 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4048
4049 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4050 {
4051 pAdapter = pAdapterNode->pAdapter;
4052
4053 if( pAdapter )
4054 {
4055 hddLog(VOS_TRACE_LEVEL_INFO,
4056 "%s: Adapter with device mode %d exists",
4057 __func__, pAdapter->device_mode);
4058 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4059 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4060 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4061 {
4062 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4063 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4064 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4065 {
4066 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4067 hddLog(VOS_TRACE_LEVEL_ERROR,
4068 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4069 "middle of WPS/EAPOL exchange.", __func__,
4070 staMac[0], staMac[1], staMac[2],
4071 staMac[3], staMac[4], staMac[5]);
4072 return VOS_FALSE;
4073 }
4074 }
4075 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4076 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4077 {
4078 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4079 {
4080 if ((pAdapter->aStaInfo[staId].isUsed) &&
4081 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4082 {
4083 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4084
4085 hddLog(VOS_TRACE_LEVEL_ERROR,
4086 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4087 "middle of WPS/EAPOL exchange.", __func__,
4088 staMac[0], staMac[1], staMac[2],
4089 staMac[3], staMac[4], staMac[5]);
4090 return VOS_FALSE;
4091 }
4092 }
4093 }
4094 }
4095 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4096 pAdapterNode = pNext;
4097 }
4098 hddLog(VOS_TRACE_LEVEL_INFO,
4099 "%s: Scan allowed", __func__);
4100 return VOS_TRUE;
4101}
4102
4103/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 * FUNCTION: wlan_hdd_cfg80211_scan
4105 * this scan respond to scan trigger and update cfg80211 scan database
4106 * later, scan dump command can be used to recieve scan results
4107 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004108int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4109#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4110 struct net_device *dev,
4111#endif
4112 struct cfg80211_scan_request *request)
4113{
4114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4115 struct net_device *dev = request->wdev->netdev;
4116#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4118 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4119 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4120 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4121 tCsrScanRequest scanRequest;
4122 tANI_U8 *channelList = NULL, i;
4123 v_U32_t scanId = 0;
4124 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004125 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004126#ifdef WLAN_FEATURE_P2P
4127 v_U8_t* pP2pIe = NULL;
4128#endif
4129
4130 ENTER();
4131
4132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4133 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004134
4135 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4136 (eConnectionState_Connecting ==
4137 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
4138 {
4139 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004140 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4141 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004142 return -EBUSY;
4143 }
4144
Jeff Johnson295189b2012-06-20 16:38:30 -07004145#ifdef WLAN_BTAMP_FEATURE
4146 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004147 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07004148 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004149 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004150 "%s: No scanning when AMP is on", __func__);
4151 return -EOPNOTSUPP;
4152 }
4153#endif
4154 //Scan on any other interface is not supported.
4155 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
4156 {
4157 hddLog(VOS_TRACE_LEVEL_ERROR,
4158 "%s: Not scanning on device_mode = %d",
4159 __func__, pAdapter->device_mode);
4160 return -EOPNOTSUPP;
4161 }
4162
4163 if (TRUE == pScanInfo->mScanPending)
4164 {
4165 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
4166 return -EBUSY;
4167 }
4168
4169 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4170 {
4171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4172 "%s:LOGP in Progress. Ignore!!!", __func__);
4173 return -EAGAIN;
4174 }
4175
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004176 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4177 {
4178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4179 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4180 return -EAGAIN;
4181 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004182 //Don't Allow Scan and return busy if Remain On
4183 //Channel and action frame is pending
4184 //Otherwise Cancel Remain On Channel and allow Scan
4185 //If no action frame pending
4186 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
4187 {
4188 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4189 return -EBUSY;
4190 }
4191
Jeff Johnson295189b2012-06-20 16:38:30 -07004192 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4193 {
4194 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004195 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004196 return -EAGAIN;
4197 }
4198 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4199 {
4200 hddLog(VOS_TRACE_LEVEL_WARN,
4201 "%s: MAX TM Level Scan not allowed", __func__);
4202 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4203 return -EBUSY;
4204 }
4205 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4206
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004207 /* Check if scan is allowed at this point of time.
4208 */
4209 if (!hdd_isScanAllowed(pHddCtx))
4210 {
4211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4212 return -EBUSY;
4213 }
4214
Jeff Johnson295189b2012-06-20 16:38:30 -07004215 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4216
4217 if (NULL != request)
4218 {
4219 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4220 (int)request->n_ssids);
4221
4222 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4223 * Becasue of this, driver is assuming that this is not wildcard scan and so
4224 * is not aging out the scan results.
4225 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004226 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 {
4228 request->n_ssids = 0;
4229 }
4230
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004231 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004232 {
4233 tCsrSSIDInfo *SsidInfo;
4234 int j;
4235 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4236 /* Allocate num_ssid tCsrSSIDInfo structure */
4237 SsidInfo = scanRequest.SSIDs.SSIDList =
4238 ( tCsrSSIDInfo *)vos_mem_malloc(
4239 request->n_ssids*sizeof(tCsrSSIDInfo));
4240
4241 if(NULL == scanRequest.SSIDs.SSIDList)
4242 {
4243 hddLog(VOS_TRACE_LEVEL_ERROR,
4244 "memory alloc failed SSIDInfo buffer");
4245 return -ENOMEM;
4246 }
4247
4248 /* copy all the ssid's and their length */
4249 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4250 {
4251 /* get the ssid length */
4252 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4253 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4254 SsidInfo->SSID.length);
4255 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4256 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4257 j, SsidInfo->SSID.ssId);
4258 }
4259 /* set the scan type to active */
4260 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4261 }
4262 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4263 {
4264 /* set the scan type to active */
4265 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4266 }
4267 else
4268 {
4269 /*Set the scan type to default type, in this case it is ACTIVE*/
4270 scanRequest.scanType = pScanInfo->scan_mode;
4271 }
4272 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4273 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4274 }
4275 else
4276 {
4277 /* set the scan type to active */
4278 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4279 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4280
4281 /* set min and max channel time to zero */
4282 scanRequest.minChnTime = 0;
4283 scanRequest.maxChnTime = 0;
4284 }
4285
4286 /* set BSSType to default type */
4287 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4288
4289 /*TODO: scan the requested channels only*/
4290
4291 /*Right now scanning all the channels */
4292 if( request )
4293 {
4294 if( request->n_channels )
4295 {
4296 channelList = vos_mem_malloc( request->n_channels );
4297 if( NULL == channelList )
4298 {
4299 status = -ENOMEM;
4300 goto free_mem;
4301 }
4302
4303 for( i = 0 ; i < request->n_channels ; i++ )
4304 channelList[i] = request->channels[i]->hw_value;
4305 }
4306
4307 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4308 scanRequest.ChannelInfo.ChannelList = channelList;
4309
4310 /* set requestType to full scan */
4311 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004312
4313 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4314 * search (Flush on both full scan and social scan but not on single
4315 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4316 */
4317
4318 /* Supplicant does single channel scan after 8-way handshake
4319 * and in that case driver shoudnt flush scan results. If
4320 * driver flushes the scan results here and unfortunately if
4321 * the AP doesnt respond to our probe req then association
4322 * fails which is not desired
4323 */
4324
4325 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4326 {
4327 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4328 pAdapter->sessionId );
4329 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004330
4331 if( request->ie_len )
4332 {
4333 /* save this for future association (join requires this) */
4334 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4335 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4336 pScanInfo->scanAddIE.length = request->ie_len;
4337
4338 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004339 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4340 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004341 )
4342 {
4343 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4344 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4345 }
4346
4347 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4348 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4349
4350#ifdef WLAN_FEATURE_P2P
4351 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4352 request->ie_len);
4353 if (pP2pIe != NULL)
4354 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004355#ifdef WLAN_FEATURE_P2P_DEBUG
4356 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4357 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4358 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4359 {
4360 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4361 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4362 "Go nego completed to Connection is started");
4363 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4364 "for 8way Handshake");
4365 }
4366 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4367 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4368 {
4369 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4370 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4371 "Disconnected state to Connection is started");
4372 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4373 "for 4way Handshake");
4374 }
4375#endif
4376
Jeff Johnsone7245742012-09-05 17:12:55 -07004377 /* no_cck will be set during p2p find to disable 11b rates */
4378 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004380 hddLog(VOS_TRACE_LEVEL_INFO,
4381 "%s: This is a P2P Search", __func__);
4382 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004383
Jeff Johnsone7245742012-09-05 17:12:55 -07004384 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4385 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004386 /* set requestType to P2P Discovery */
4387 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004388 }
4389
4390 /*
4391 Skip Dfs Channel in case of P2P Search
4392 if it is set in ini file
4393 */
4394 if(cfg_param->skipDfsChnlInP2pSearch)
4395 {
4396 scanRequest.skipDfsChnlInP2pSearch = 1;
4397 }
4398 else
4399 {
4400 scanRequest.skipDfsChnlInP2pSearch = 0;
4401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004402
Jeff Johnson295189b2012-06-20 16:38:30 -07004403 }
4404 }
4405#endif
4406 }
4407 }
4408
4409 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4410
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004411 /* acquire the wakelock to avoid the apps suspend during the scan. To
4412 * address the following issues.
4413 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4414 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4415 * for long time, this result in apps running at full power for long time.
4416 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4417 * be stuck in full power because of resume BMPS
4418 */
4419 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004420
4421 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 pAdapter->sessionId, &scanRequest, &scanId,
4423 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004424
Jeff Johnson295189b2012-06-20 16:38:30 -07004425 if (eHAL_STATUS_SUCCESS != status)
4426 {
4427 hddLog(VOS_TRACE_LEVEL_ERROR,
4428 "%s: sme_ScanRequest returned error %d", __func__, status);
4429 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004430 if(eHAL_STATUS_RESOURCES == status)
4431 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004432 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 -07004433 status = -EBUSY;
4434 } else {
4435 status = -EIO;
4436 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004437 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004438 goto free_mem;
4439 }
4440
4441 pScanInfo->mScanPending = TRUE;
4442 pAdapter->request = request;
4443 pScanInfo->scanId = scanId;
4444
4445 complete(&pScanInfo->scan_req_completion_event);
4446
4447free_mem:
4448 if( scanRequest.SSIDs.SSIDList )
4449 {
4450 vos_mem_free(scanRequest.SSIDs.SSIDList);
4451 }
4452
4453 if( channelList )
4454 vos_mem_free( channelList );
4455
4456 EXIT();
4457
4458 return status;
4459}
4460
4461/*
4462 * FUNCTION: wlan_hdd_cfg80211_connect_start
4463 * This function is used to start the association process
4464 */
4465int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004466 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004467{
4468 int status = 0;
4469 hdd_wext_state_t *pWextState;
4470 v_U32_t roamId;
4471 tCsrRoamProfile *pRoamProfile;
4472 eMib_dot11DesiredBssType connectedBssType;
4473 eCsrAuthType RSNAuthType;
4474
4475 ENTER();
4476
4477 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4478
4479 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4480 {
4481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4482 return -EINVAL;
4483 }
4484
4485 pRoamProfile = &pWextState->roamProfile;
4486
4487 if (pRoamProfile)
4488 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004489 int ret = 0;
4490 hdd_station_ctx_t *pHddStaCtx;
4491 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4492 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4493
4494 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4495 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4496 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004497 {
4498 /* Issue disconnect to CSR */
4499 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4500 if( eHAL_STATUS_SUCCESS ==
4501 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4502 pAdapter->sessionId,
4503 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4504 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004505 ret = wait_for_completion_interruptible_timeout(
4506 &pAdapter->disconnect_comp_var,
4507 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4508 if (0 == ret)
4509 {
4510 VOS_ASSERT(0);
4511 }
4512 }
4513 }
4514 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4515 {
4516 ret = wait_for_completion_interruptible_timeout(
4517 &pAdapter->disconnect_comp_var,
4518 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4519 if (0 == ret)
4520 {
4521 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004522 }
4523 }
4524
4525 if (HDD_WMM_USER_MODE_NO_QOS ==
4526 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4527 {
4528 /*QoS not enabled in cfg file*/
4529 pRoamProfile->uapsd_mask = 0;
4530 }
4531 else
4532 {
4533 /*QoS enabled, update uapsd mask from cfg file*/
4534 pRoamProfile->uapsd_mask =
4535 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4536 }
4537
4538 pRoamProfile->SSIDs.numOfSSIDs = 1;
4539 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4540 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4541 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4542 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4543 ssid, ssid_len);
4544
4545 if (bssid)
4546 {
4547 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4548 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4549 WNI_CFG_BSSID_LEN);
4550 /* Save BSSID in seperate variable as well, as RoamProfile
4551 BSSID is getting zeroed out in the association process. And in
4552 case of join failure we should send valid BSSID to supplicant
4553 */
4554 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4555 WNI_CFG_BSSID_LEN);
4556 }
4557
4558 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4559 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4560 {
4561 /*set gen ie*/
4562 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4563 /*set auth*/
4564 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4565 }
4566 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4567 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4568 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4569 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4570 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4571 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4572 )
4573 {
4574 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4575 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4576 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4577 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4578 eCSR_AUTH_TYPE_AUTOSWITCH;
4579 pWextState->roamProfile.AuthType.authType[0] =
4580 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4581 }
4582#ifdef FEATURE_WLAN_WAPI
4583 if (pAdapter->wapi_info.nWapiMode)
4584 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004585 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004586 switch (pAdapter->wapi_info.wapiAuthMode)
4587 {
4588 case WAPI_AUTH_MODE_PSK:
4589 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004590 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004591 pAdapter->wapi_info.wapiAuthMode);
4592 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4593 break;
4594 }
4595 case WAPI_AUTH_MODE_CERT:
4596 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004597 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004598 pAdapter->wapi_info.wapiAuthMode);
4599 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4600 break;
4601 }
4602 } // End of switch
4603 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4604 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4605 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004606 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004607 pRoamProfile->AuthType.numEntries = 1;
4608 pRoamProfile->EncryptionType.numEntries = 1;
4609 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4610 pRoamProfile->mcEncryptionType.numEntries = 1;
4611 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4612 }
4613 }
4614#endif /* FEATURE_WLAN_WAPI */
4615 pRoamProfile->csrPersona = pAdapter->device_mode;
4616
Jeff Johnson32d95a32012-09-10 13:15:23 -07004617 if( operatingChannel )
4618 {
4619 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4620 pRoamProfile->ChannelInfo.numOfChannels = 1;
4621 }
4622
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004623 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4624 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4625 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4626 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004627 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4628 */
4629 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4630 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4631 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004632
Jeff Johnson295189b2012-06-20 16:38:30 -07004633 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4634 pAdapter->sessionId, pRoamProfile, &roamId);
4635
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004636 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304637 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4638
4639 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4641 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4642 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304643 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004644 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304645 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004646
4647 pRoamProfile->ChannelInfo.ChannelList = NULL;
4648 pRoamProfile->ChannelInfo.numOfChannels = 0;
4649
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 }
4651 else
4652 {
4653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4654 return -EINVAL;
4655 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004656 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004657 return status;
4658}
4659
4660/*
4661 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4662 * This function is used to set the authentication type (OPEN/SHARED).
4663 *
4664 */
4665static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4666 enum nl80211_auth_type auth_type)
4667{
4668 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4669 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4670
4671 ENTER();
4672
4673 /*set authentication type*/
4674 switch (auth_type)
4675 {
4676 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4677 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004678#ifdef WLAN_FEATURE_VOWIFI_11R
4679 case NL80211_AUTHTYPE_FT:
4680#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004681 hddLog(VOS_TRACE_LEVEL_INFO,
4682 "%s: set authentication type to OPEN", __func__);
4683 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4684 break;
4685
4686 case NL80211_AUTHTYPE_SHARED_KEY:
4687 hddLog(VOS_TRACE_LEVEL_INFO,
4688 "%s: set authentication type to SHARED", __func__);
4689 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4690 break;
4691#ifdef FEATURE_WLAN_CCX
4692 case NL80211_AUTHTYPE_NETWORK_EAP:
4693 hddLog(VOS_TRACE_LEVEL_INFO,
4694 "%s: set authentication type to CCKM WPA", __func__);
4695 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4696 break;
4697#endif
4698
4699
4700 default:
4701 hddLog(VOS_TRACE_LEVEL_ERROR,
4702 "%s: Unsupported authentication type %d", __func__,
4703 auth_type);
4704 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4705 return -EINVAL;
4706 }
4707
4708 pWextState->roamProfile.AuthType.authType[0] =
4709 pHddStaCtx->conn_info.authType;
4710 return 0;
4711}
4712
4713/*
4714 * FUNCTION: wlan_hdd_set_akm_suite
4715 * This function is used to set the key mgmt type(PSK/8021x).
4716 *
4717 */
4718static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4719 u32 key_mgmt
4720 )
4721{
4722 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4723 ENTER();
4724
4725 /*set key mgmt type*/
4726 switch(key_mgmt)
4727 {
4728 case WLAN_AKM_SUITE_PSK:
4729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4730 __func__);
4731 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4732 break;
4733
4734 case WLAN_AKM_SUITE_8021X:
4735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4736 __func__);
4737 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4738 break;
4739#ifdef FEATURE_WLAN_CCX
4740#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4741#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4742 case WLAN_AKM_SUITE_CCKM:
4743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4744 __func__);
4745 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4746 break;
4747#endif
4748
4749 default:
4750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4751 __func__, key_mgmt);
4752 return -EINVAL;
4753
4754 }
4755 return 0;
4756}
4757
4758/*
4759 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4760 * This function is used to set the encryption type
4761 * (NONE/WEP40/WEP104/TKIP/CCMP).
4762 */
4763static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4764 u32 cipher,
4765 bool ucast
4766 )
4767{
4768 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4769 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4770 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4771
4772 ENTER();
4773
4774 if (!cipher)
4775 {
4776 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4777 __func__, cipher);
4778 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4779 }
4780 else
4781 {
4782
4783 /*set encryption method*/
4784 switch (cipher)
4785 {
4786 case IW_AUTH_CIPHER_NONE:
4787 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4788 break;
4789
4790 case WLAN_CIPHER_SUITE_WEP40:
4791 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4792 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4793 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4794 else
4795 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4796 break;
4797
4798 case WLAN_CIPHER_SUITE_WEP104:
4799 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4800 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4801 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4802 else
4803 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4804 break;
4805
4806 case WLAN_CIPHER_SUITE_TKIP:
4807 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4808 break;
4809
4810 case WLAN_CIPHER_SUITE_CCMP:
4811 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4812 break;
4813#ifdef FEATURE_WLAN_WAPI
4814 case WLAN_CIPHER_SUITE_SMS4:
4815 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4816 break;
4817#endif
4818
4819#ifdef FEATURE_WLAN_CCX
4820 case WLAN_CIPHER_SUITE_KRK:
4821 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4822 break;
4823#endif
4824 default:
4825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4826 __func__, cipher);
4827 return -EOPNOTSUPP;
4828 }
4829 }
4830
4831 if (ucast)
4832 {
4833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4834 __func__, encryptionType);
4835 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4836 pWextState->roamProfile.EncryptionType.numEntries = 1;
4837 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4838 encryptionType;
4839 }
4840 else
4841 {
4842 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4843 __func__, encryptionType);
4844 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4845 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4846 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4847 }
4848
4849 return 0;
4850}
4851
4852
4853/*
4854 * FUNCTION: wlan_hdd_cfg80211_set_ie
4855 * This function is used to parse WPA/RSN IE's.
4856 */
4857int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4858 u8 *ie,
4859 size_t ie_len
4860 )
4861{
4862 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4863 u8 *genie = ie;
4864 v_U16_t remLen = ie_len;
4865#ifdef FEATURE_WLAN_WAPI
4866 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4867 u16 *tmp;
4868 v_U16_t akmsuiteCount;
4869 int *akmlist;
4870#endif
4871 ENTER();
4872
4873 /* clear previous assocAddIE */
4874 pWextState->assocAddIE.length = 0;
4875 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4876
4877 while (remLen >= 2)
4878 {
4879 v_U16_t eLen = 0;
4880 v_U8_t elementId;
4881 elementId = *genie++;
4882 eLen = *genie++;
4883 remLen -= 2;
4884
4885 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4886 __func__, elementId, eLen);
4887
4888 switch ( elementId )
4889 {
4890 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004891 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 -07004892 {
4893 hddLog(VOS_TRACE_LEVEL_ERROR,
4894 "%s: Invalid WPA IE", __func__);
4895 return -EINVAL;
4896 }
4897 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4898 {
4899 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4900 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4901 __func__, eLen + 2);
4902
4903 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4904 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004905 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4906 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004907 VOS_ASSERT(0);
4908 return -ENOMEM;
4909 }
4910 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4911 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4912 pWextState->assocAddIE.length += eLen + 2;
4913
4914 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4915 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4916 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4917 }
4918 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4919 {
4920 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4921 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4922 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4923 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4924 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4925 }
4926#ifdef WLAN_FEATURE_P2P
4927 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4928 P2P_OUI_TYPE_SIZE))
4929 /*Consider P2P IE, only for P2P Client */
4930 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4931 {
4932 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4933 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4934 __func__, eLen + 2);
4935
4936 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4937 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004938 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4939 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 VOS_ASSERT(0);
4941 return -ENOMEM;
4942 }
4943 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4944 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4945 pWextState->assocAddIE.length += eLen + 2;
4946
4947 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4948 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4949 }
4950#endif
4951#ifdef WLAN_FEATURE_WFD
4952 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4953 WFD_OUI_TYPE_SIZE))
4954 /*Consider WFD IE, only for P2P Client */
4955 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4956 {
4957 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4958 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4959 __func__, eLen + 2);
4960
4961 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4962 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004963 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4964 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004965 VOS_ASSERT(0);
4966 return -ENOMEM;
4967 }
4968 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4969 // WPS IE + P2P IE + WFD IE
4970 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4971 pWextState->assocAddIE.length += eLen + 2;
4972
4973 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4974 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4975 }
4976#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004977 /* Appending HS 2.0 Indication Element in Assiciation Request */
4978 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004979 HS20_OUI_TYPE_SIZE)) )
4980 {
4981 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4982 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4983 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004984
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004985 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4986 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004987 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4988 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004989 VOS_ASSERT(0);
4990 return -ENOMEM;
4991 }
4992 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4993 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004994
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004995 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4996 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4997 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004998
Jeff Johnson295189b2012-06-20 16:38:30 -07004999 break;
5000 case DOT11F_EID_RSN:
5001 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5002 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5003 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5004 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5005 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5006 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005007 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5008 case DOT11F_EID_EXTCAP:
5009 {
5010 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5011 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5012 __func__, eLen + 2);
5013
5014 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5015 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005016 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5017 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005018 VOS_ASSERT(0);
5019 return -ENOMEM;
5020 }
5021 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5022 pWextState->assocAddIE.length += eLen + 2;
5023
5024 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5025 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5026 break;
5027 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005028#ifdef FEATURE_WLAN_WAPI
5029 case WLAN_EID_WAPI:
5030 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5031 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5032 pAdapter->wapi_info.nWapiMode);
5033 tmp = (u16 *)ie;
5034 tmp = tmp + 2; // Skip element Id and Len, Version
5035 akmsuiteCount = WPA_GET_LE16(tmp);
5036 tmp = tmp + 1;
5037 akmlist = (int *)(tmp);
5038 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5039 {
5040 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5041 }
5042 else
5043 {
5044 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5045 VOS_ASSERT(0);
5046 return -EINVAL;
5047 }
5048
5049 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5050 {
5051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005052 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005053 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5054 }
5055 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5056 {
5057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005058 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5060 }
5061 break;
5062#endif
5063 default:
5064 hddLog (VOS_TRACE_LEVEL_ERROR,
5065 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005066 /* when Unknown IE is received we should break and continue
5067 * to the next IE in the buffer instead we were returning
5068 * so changing this to break */
5069 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 }
5071 genie += eLen;
5072 remLen -= eLen;
5073 }
5074 EXIT();
5075 return 0;
5076}
5077
5078/*
5079 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5080 * This function is used to initialize the security
5081 * parameters during connect operation.
5082 */
5083int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5084 struct cfg80211_connect_params *req
5085 )
5086{
5087 int status = 0;
5088 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5089 ENTER();
5090
5091 /*set wpa version*/
5092 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5093
5094 if (req->crypto.wpa_versions)
5095 {
5096 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5097 && ( (req->ie_len)
5098 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5099 // Make sure that it is including a WPA IE.
5100 /* Currently NL is putting WPA version 1 even for open,
5101 * since p2p ie is also put in same buffer.
5102 * */
5103 {
5104 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5105 }
5106 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5107 {
5108 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5109 }
5110 }
5111
5112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5113 pWextState->wpaVersion);
5114
5115 /*set authentication type*/
5116 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5117
5118 if (0 > status)
5119 {
5120 hddLog(VOS_TRACE_LEVEL_ERROR,
5121 "%s: failed to set authentication type ", __func__);
5122 return status;
5123 }
5124
5125 /*set key mgmt type*/
5126 if (req->crypto.n_akm_suites)
5127 {
5128 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5129 if (0 > status)
5130 {
5131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5132 __func__);
5133 return status;
5134 }
5135 }
5136
5137 /*set pairwise cipher type*/
5138 if (req->crypto.n_ciphers_pairwise)
5139 {
5140 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5141 req->crypto.ciphers_pairwise[0], true);
5142 if (0 > status)
5143 {
5144 hddLog(VOS_TRACE_LEVEL_ERROR,
5145 "%s: failed to set unicast cipher type", __func__);
5146 return status;
5147 }
5148 }
5149 else
5150 {
5151 /*Reset previous cipher suite to none*/
5152 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5153 if (0 > status)
5154 {
5155 hddLog(VOS_TRACE_LEVEL_ERROR,
5156 "%s: failed to set unicast cipher type", __func__);
5157 return status;
5158 }
5159 }
5160
5161 /*set group cipher type*/
5162 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5163 false);
5164
5165 if (0 > status)
5166 {
5167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5168 __func__);
5169 return status;
5170 }
5171
5172 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5173 if (req->ie_len)
5174 {
5175 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5176 if ( 0 > status)
5177 {
5178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5179 __func__);
5180 return status;
5181 }
5182 }
5183
5184 /*incase of WEP set default key information*/
5185 if (req->key && req->key_len)
5186 {
5187 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5188 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5189 )
5190 {
5191 if ( IW_AUTH_KEY_MGMT_802_1X
5192 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5193 {
5194 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5195 __func__);
5196 return -EOPNOTSUPP;
5197 }
5198 else
5199 {
5200 u8 key_len = req->key_len;
5201 u8 key_idx = req->key_idx;
5202
5203 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5204 && (CSR_MAX_NUM_KEY > key_idx)
5205 )
5206 {
5207 hddLog(VOS_TRACE_LEVEL_INFO,
5208 "%s: setting default wep key, key_idx = %hu key_len %hu",
5209 __func__, key_idx, key_len);
5210 vos_mem_copy(
5211 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5212 req->key, key_len);
5213 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5214 (u8)key_len;
5215 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5216 }
5217 }
5218 }
5219 }
5220
5221 return status;
5222}
5223
5224/*
5225 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5226 * This function is used to initialize the security
5227 * parameters during connect operation.
5228 */
5229static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5230 struct net_device *ndev,
5231 struct cfg80211_connect_params *req
5232 )
5233{
5234 int status = 0;
5235 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5236 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5237 hdd_context_t *pHddCtx = NULL;
5238
5239 ENTER();
5240
5241 hddLog(VOS_TRACE_LEVEL_INFO,
5242 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5243
5244 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5245 {
5246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5247 "%s:LOGP in Progress. Ignore!!!", __func__);
5248 return -EAGAIN;
5249 }
5250
5251#ifdef WLAN_BTAMP_FEATURE
5252 //Infra connect not supported when AMP traffic is on.
5253 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5254 {
5255 hddLog(VOS_TRACE_LEVEL_ERROR,
5256 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005257 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 }
5259#endif
5260 /*initialise security parameters*/
5261 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5262
5263 if ( 0 > status)
5264 {
5265 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5266 __func__);
5267 return status;
5268 }
5269
5270 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005271 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005272 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5273 (vos_concurrent_sessions_running()))
5274 {
5275 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5276
5277 if (NULL != pVosContext)
5278 {
5279 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5280 if(NULL != pHddCtx)
5281 {
5282 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5283 }
5284 }
5285 }
5286
Mohit Khanna765234a2012-09-11 15:08:35 -07005287 if ( req->channel )
5288 {
5289 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5290 req->ssid_len, req->bssid,
5291 req->channel->hw_value);
5292 }
5293 else
5294 {
5295 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5296 req->ssid_len, req->bssid,
5297 0);
5298 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005299
5300 if (0 > status)
5301 {
5302 //ReEnable BMPS if disabled
5303 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5304 (NULL != pHddCtx))
5305 {
5306 //ReEnable Bmps and Imps back
5307 hdd_enable_bmps_imps(pHddCtx);
5308 }
5309
5310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5311 return status;
5312 }
5313 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5314 EXIT();
5315 return status;
5316}
5317
5318
5319/*
5320 * FUNCTION: wlan_hdd_cfg80211_disconnect
5321 * This function is used to issue a disconnect request to SME
5322 */
5323static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5324 struct net_device *dev,
5325 u16 reason
5326 )
5327{
5328 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5329 tCsrRoamProfile *pRoamProfile =
5330 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5331 int status = 0;
5332 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005333#ifdef FEATURE_WLAN_TDLS
5334 tANI_U8 staIdx;
5335#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005336
5337 ENTER();
5338
5339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5340 __func__,pAdapter->device_mode);
5341
5342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5343 __func__, reason);
5344
5345 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5346 {
5347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5348 "%s:LOGP in Progress. Ignore!!!",__func__);
5349 return -EAGAIN;
5350 }
5351 if (NULL != pRoamProfile)
5352 {
5353 /*issue disconnect request to SME, if station is in connected state*/
5354 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5355 {
5356 eCsrRoamDisconnectReason reasonCode =
5357 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5358 switch(reason)
5359 {
5360 case WLAN_REASON_MIC_FAILURE:
5361 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5362 break;
5363
5364 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5365 case WLAN_REASON_DISASSOC_AP_BUSY:
5366 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5367 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5368 break;
5369
5370 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5371 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5372 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5373 break;
5374
5375 case WLAN_REASON_DEAUTH_LEAVING:
5376 default:
5377 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5378 break;
5379 }
5380 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5381 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5382 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5383
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005384#ifdef FEATURE_WLAN_TDLS
5385 /* First clean up the tdls peers if any */
5386 for (staIdx = 1 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
5387 {
5388 if (pHddStaCtx->conn_info.staId[staIdx])
5389 {
5390 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
5391 pAdapter->sessionId,
5392 pHddStaCtx->conn_info.peerMacAddress[staIdx].bytes);
5393 }
5394 }
5395#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005396 /*issue disconnect*/
5397 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5398 pAdapter->sessionId, reasonCode);
5399
5400 if ( 0 != status)
5401 {
5402 hddLog(VOS_TRACE_LEVEL_ERROR,
5403 "%s csrRoamDisconnect failure, returned %d \n",
5404 __func__, (int)status );
5405 return -EINVAL;
5406 }
5407
5408 wait_for_completion_interruptible_timeout(
5409 &pAdapter->disconnect_comp_var,
5410 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5411
5412
5413 /*stop tx queues*/
5414 netif_tx_disable(dev);
5415 netif_carrier_off(dev);
5416 }
5417 }
5418 else
5419 {
5420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5421 }
5422
5423 return status;
5424}
5425
5426/*
5427 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5428 * This function is used to initialize the security
5429 * settings in IBSS mode.
5430 */
5431static int wlan_hdd_cfg80211_set_privacy_ibss(
5432 hdd_adapter_t *pAdapter,
5433 struct cfg80211_ibss_params *params
5434 )
5435{
5436 int status = 0;
5437 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5438 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5440
5441 ENTER();
5442
5443 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5444
5445 if (params->ie_len && ( NULL != params->ie) )
5446 {
5447 if (WLAN_EID_RSN == params->ie[0])
5448 {
5449 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5450 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5451 }
5452 else
5453 {
5454 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5455 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5456 }
5457 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5458
5459 if (0 > status)
5460 {
5461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5462 __func__);
5463 return status;
5464 }
5465 }
5466
5467 pWextState->roamProfile.AuthType.authType[0] =
5468 pHddStaCtx->conn_info.authType =
5469 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5470
5471 if (params->privacy)
5472 {
5473 /* Security enabled IBSS, At this time there is no information available
5474 * about the security paramters, so initialise the encryption type to
5475 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5476 * The correct security parameters will be updated later in
5477 * wlan_hdd_cfg80211_add_key */
5478 /* Hal expects encryption type to be set inorder
5479 *enable privacy bit in beacons */
5480
5481 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5482 }
5483
5484 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5485 pWextState->roamProfile.EncryptionType.numEntries = 1;
5486 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5487
5488 return status;
5489}
5490
5491/*
5492 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5493 * This function is used to create/join an IBSS
5494 */
5495static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5496 struct net_device *dev,
5497 struct cfg80211_ibss_params *params
5498 )
5499{
5500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5501 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5502 tCsrRoamProfile *pRoamProfile;
5503 int status;
5504 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5505
5506 ENTER();
5507
5508 hddLog(VOS_TRACE_LEVEL_INFO,
5509 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5510
5511 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5512 {
5513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5514 "%s:LOGP in Progress. Ignore!!!", __func__);
5515 return -EAGAIN;
5516 }
5517
5518 if (NULL == pWextState)
5519 {
5520 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5521 __func__);
5522 return -EIO;
5523 }
5524
5525 pRoamProfile = &pWextState->roamProfile;
5526
5527 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5528 {
5529 hddLog (VOS_TRACE_LEVEL_ERROR,
5530 "%s Interface type is not set to IBSS \n", __func__);
5531 return -EINVAL;
5532 }
5533
5534 /* Set Channel */
5535 if (NULL != params->channel)
5536 {
5537 u8 channelNum;
5538 if (IEEE80211_BAND_5GHZ == params->channel->band)
5539 {
5540 hddLog(VOS_TRACE_LEVEL_ERROR,
5541 "%s: IBSS join is called with unsupported band %d",
5542 __func__, params->channel->band);
5543 return -EOPNOTSUPP;
5544 }
5545
5546 /* Get channel number */
5547 channelNum =
5548 ieee80211_frequency_to_channel(params->channel->center_freq);
5549
5550 /*TODO: use macro*/
5551 if (14 >= channelNum)
5552 {
5553 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5554 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5555 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5556 int indx;
5557
5558 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5559 validChan, &numChans))
5560 {
5561 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5562 __func__);
5563 return -EOPNOTSUPP;
5564 }
5565
5566 for (indx = 0; indx < numChans; indx++)
5567 {
5568 if (channelNum == validChan[indx])
5569 {
5570 break;
5571 }
5572 }
5573 if (indx >= numChans)
5574 {
5575 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5576 __func__, channelNum);
5577 return -EINVAL;
5578 }
5579 /* Set the Operational Channel */
5580 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5581 channelNum);
5582 pRoamProfile->ChannelInfo.numOfChannels = 1;
5583 pHddStaCtx->conn_info.operationChannel = channelNum;
5584 pRoamProfile->ChannelInfo.ChannelList =
5585 &pHddStaCtx->conn_info.operationChannel;
5586 }
5587 else
5588 {
5589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5590 __func__, channelNum);
5591 return -EINVAL;
5592 }
5593 }
5594
5595 /* Initialize security parameters */
5596 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5597 if (status < 0)
5598 {
5599 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5600 __func__);
5601 return status;
5602 }
5603
5604 /* Issue connect start */
5605 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005606 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005607
5608 if (0 > status)
5609 {
5610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5611 return status;
5612 }
5613
5614 return 0;
5615}
5616
5617/*
5618 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5619 * This function is used to leave an IBSS
5620 */
5621static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5622 struct net_device *dev
5623 )
5624{
5625 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5626 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5627 tCsrRoamProfile *pRoamProfile;
5628
5629 ENTER();
5630
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005631 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5632 {
5633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5634 "%s:LOGP in Progress. Ignore!!!", __func__);
5635 return -EAGAIN;
5636 }
5637
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5639 if (NULL == pWextState)
5640 {
5641 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5642 __func__);
5643 return -EIO;
5644 }
5645
5646 pRoamProfile = &pWextState->roamProfile;
5647
5648 /* Issue disconnect only if interface type is set to IBSS */
5649 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5650 {
5651 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5652 __func__);
5653 return -EINVAL;
5654 }
5655
5656 /* Issue Disconnect request */
5657 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5658 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5659 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5660
5661 return 0;
5662}
5663
5664/*
5665 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5666 * This function is used to set the phy parameters
5667 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5668 */
5669static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5670 u32 changed)
5671{
5672 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5673 tHalHandle hHal = pHddCtx->hHal;
5674
5675 ENTER();
5676
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005677 if ( pHddCtx->isLogpInProgress )
5678 {
5679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5680 "%s:LOGP in Progress. Ignore!!!", __func__);
5681 return -EAGAIN;
5682 }
5683
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5685 {
5686 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5687 WNI_CFG_RTS_THRESHOLD_STAMAX :
5688 wiphy->rts_threshold;
5689
5690 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5691 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5692 {
5693 hddLog(VOS_TRACE_LEVEL_ERROR,
5694 "%s: Invalid RTS Threshold value %hu",
5695 __func__, rts_threshold);
5696 return -EINVAL;
5697 }
5698
5699 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5700 rts_threshold, ccmCfgSetCallback,
5701 eANI_BOOLEAN_TRUE))
5702 {
5703 hddLog(VOS_TRACE_LEVEL_ERROR,
5704 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5705 __func__, rts_threshold);
5706 return -EIO;
5707 }
5708
5709 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5710 rts_threshold);
5711 }
5712
5713 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5714 {
5715 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5716 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5717 wiphy->frag_threshold;
5718
5719 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5720 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5721 {
5722 hddLog(VOS_TRACE_LEVEL_ERROR,
5723 "%s: Invalid frag_threshold value %hu", __func__,
5724 frag_threshold);
5725 return -EINVAL;
5726 }
5727
5728 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5729 frag_threshold, ccmCfgSetCallback,
5730 eANI_BOOLEAN_TRUE))
5731 {
5732 hddLog(VOS_TRACE_LEVEL_ERROR,
5733 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5734 __func__, frag_threshold);
5735 return -EIO;
5736 }
5737
5738 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5739 frag_threshold);
5740 }
5741
5742 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5743 || (changed & WIPHY_PARAM_RETRY_LONG))
5744 {
5745 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5746 wiphy->retry_short :
5747 wiphy->retry_long;
5748
5749 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5750 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5751 {
5752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5753 __func__, retry_value);
5754 return -EINVAL;
5755 }
5756
5757 if (changed & WIPHY_PARAM_RETRY_SHORT)
5758 {
5759 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5760 retry_value, ccmCfgSetCallback,
5761 eANI_BOOLEAN_TRUE))
5762 {
5763 hddLog(VOS_TRACE_LEVEL_ERROR,
5764 "%s: ccmCfgSetInt failed for long retry count %hu",
5765 __func__, retry_value);
5766 return -EIO;
5767 }
5768 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5769 __func__, retry_value);
5770 }
5771 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5772 {
5773 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5774 retry_value, ccmCfgSetCallback,
5775 eANI_BOOLEAN_TRUE))
5776 {
5777 hddLog(VOS_TRACE_LEVEL_ERROR,
5778 "%s: ccmCfgSetInt failed for short retry count %hu",
5779 __func__, retry_value);
5780 return -EIO;
5781 }
5782 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5783 __func__, retry_value);
5784 }
5785 }
5786
5787 return 0;
5788}
5789
5790/*
5791 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5792 * This function is used to set the txpower
5793 */
5794static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5795#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5796 enum tx_power_setting type,
5797#else
5798 enum nl80211_tx_power_setting type,
5799#endif
5800 int dbm)
5801{
5802 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5803 tHalHandle hHal = pHddCtx->hHal;
5804 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5805 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5806
5807 ENTER();
5808
5809 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5810 dbm, ccmCfgSetCallback,
5811 eANI_BOOLEAN_TRUE))
5812 {
5813 hddLog(VOS_TRACE_LEVEL_ERROR,
5814 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5815 return -EIO;
5816 }
5817
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005818 if ( pHddCtx->isLogpInProgress )
5819 {
5820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5821 "%s:LOGP in Progress. Ignore!!!", __func__);
5822 return -EAGAIN;
5823 }
5824
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5826 dbm);
5827
5828 switch(type)
5829 {
5830 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5831 /* Fall through */
5832 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5833 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5834 {
5835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5836 __func__);
5837 return -EIO;
5838 }
5839 break;
5840 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5842 __func__);
5843 return -EOPNOTSUPP;
5844 break;
5845 default:
5846 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5847 __func__, type);
5848 return -EIO;
5849 }
5850
5851 return 0;
5852}
5853
5854/*
5855 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5856 * This function is used to read the txpower
5857 */
5858static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5859{
5860
5861 hdd_adapter_t *pAdapter;
5862 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5863
Jeff Johnsone7245742012-09-05 17:12:55 -07005864 ENTER();
5865
Jeff Johnson295189b2012-06-20 16:38:30 -07005866 if (NULL == pHddCtx)
5867 {
5868 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5869 *dbm = 0;
5870 return -ENOENT;
5871 }
5872
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005873 if ( pHddCtx->isLogpInProgress )
5874 {
5875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5876 "%s:LOGP in Progress. Ignore!!!", __func__);
5877 return -EAGAIN;
5878 }
5879
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5881 if (NULL == pAdapter)
5882 {
5883 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5884 return -ENOENT;
5885 }
5886
5887 wlan_hdd_get_classAstats(pAdapter);
5888 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5889
Jeff Johnsone7245742012-09-05 17:12:55 -07005890 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 return 0;
5892}
5893
5894static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5895 u8* mac, struct station_info *sinfo)
5896{
5897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5898 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5899 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5900 tANI_U8 rate_flags;
5901
5902 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5903 hdd_config_t *pCfg = pHddCtx->cfg_ini;
5904 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5905
5906 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5907 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5908 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5909 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5910 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5911 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5912 tANI_U16 maxRate = 0;
5913 tANI_U16 myRate;
5914 tANI_U16 currentRate = 0;
5915 tANI_U8 maxSpeedMCS = 0;
5916 tANI_U8 maxMCSIdx = 0;
5917 tANI_U8 rateFlag = 1;
5918 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005919 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005920
Jeff Johnsone7245742012-09-05 17:12:55 -07005921 ENTER();
5922
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5924 (0 == ssidlen))
5925 {
5926 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5927 " Invalid ssidlen, %d", __func__, ssidlen);
5928 /*To keep GUI happy*/
5929 return 0;
5930 }
5931
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005932 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5933 {
5934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5935 "%s:LOGP in Progress. Ignore!!!", __func__);
5936 return -EAGAIN;
5937 }
5938
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5940 sinfo->filled |= STATION_INFO_SIGNAL;
5941
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005942 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5944
5945 //convert to the UI units of 100kbps
5946 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5947
5948#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005949 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 -07005950 sinfo->signal,
5951 pCfg->reportMaxLinkSpeed,
5952 myRate,
5953 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005954 (int) pCfg->linkSpeedRssiMid,
5955 (int) pCfg->linkSpeedRssiLow,
5956 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005957#endif //LINKSPEED_DEBUG_ENABLED
5958
5959 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5960 {
5961 // we do not want to necessarily report the current speed
5962 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5963 {
5964 // report the max possible speed
5965 rssidx = 0;
5966 }
5967 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5968 {
5969 // report the max possible speed with RSSI scaling
5970 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5971 {
5972 // report the max possible speed
5973 rssidx = 0;
5974 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005975 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 {
5977 // report middle speed
5978 rssidx = 1;
5979 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005980 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5981 {
5982 // report middle speed
5983 rssidx = 2;
5984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 else
5986 {
5987 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005988 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 }
5990 }
5991 else
5992 {
5993 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5994 hddLog(VOS_TRACE_LEVEL_ERROR,
5995 "%s: Invalid value for reportMaxLinkSpeed: %u",
5996 __func__, pCfg->reportMaxLinkSpeed);
5997 rssidx = 0;
5998 }
5999
6000 maxRate = 0;
6001
6002 /* Get Basic Rate Set */
6003 ccmCfgGetStr(hHal, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, &ORLeng);
6004 for (i = 0; i < ORLeng; i++)
6005 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006006 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 {
6008 /* Validate Rate Set */
6009 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6010 {
6011 currentRate = supported_data_rate[j].supported_rate[rssidx];
6012 break;
6013 }
6014 }
6015 /* Update MAX rate */
6016 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6017 }
6018
6019 /* Get Extended Rate Set */
6020 ccmCfgGetStr(hHal, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedRates, &ERLeng);
6021 for (i = 0; i < ERLeng; i++)
6022 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006023 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 {
6025 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6026 {
6027 currentRate = supported_data_rate[j].supported_rate[rssidx];
6028 break;
6029 }
6030 }
6031 /* Update MAX rate */
6032 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6033 }
6034
6035 /* Get MCS Rate Set -- but only if we are connected at MCS
6036 rates or if we are always reporting max speed or if we have
6037 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006038 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 {
6040 ccmCfgGetStr(hHal, WNI_CFG_CURRENT_MCS_SET, MCSRates, &MCSLeng);
6041 rateFlag = 0;
6042 if (rate_flags & eHAL_TX_RATE_HT40)
6043 {
6044 rateFlag |= 1;
6045 }
6046 if (rate_flags & eHAL_TX_RATE_SGI)
6047 {
6048 rateFlag |= 2;
6049 }
6050
6051 for (i = 0; i < MCSLeng; i++)
6052 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006053 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6054 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 {
6056 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6057 {
6058 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6059 break;
6060 }
6061 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006062 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 {
6064 maxRate = currentRate;
6065 maxSpeedMCS = 1;
6066 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6067 }
6068 }
6069 }
6070
6071 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006072 if (((maxRate < myRate) && (0 == rssidx)) ||
6073 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 {
6075 maxRate = myRate;
6076 if (rate_flags & eHAL_TX_RATE_LEGACY)
6077 {
6078 maxSpeedMCS = 0;
6079 }
6080 else
6081 {
6082 maxSpeedMCS = 1;
6083 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6084 }
6085 }
6086
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006087 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 {
6089 sinfo->txrate.legacy = maxRate;
6090#ifdef LINKSPEED_DEBUG_ENABLED
6091 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6092#endif //LINKSPEED_DEBUG_ENABLED
6093 }
6094 else
6095 {
6096 sinfo->txrate.mcs = maxMCSIdx;
6097 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6098 if (rate_flags & eHAL_TX_RATE_SGI)
6099 {
6100 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6101 }
6102 if (rate_flags & eHAL_TX_RATE_HT40)
6103 {
6104 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6105 }
6106#ifdef LINKSPEED_DEBUG_ENABLED
6107 pr_info("Reporting MCS rate %d flags %x\n",
6108 sinfo->txrate.mcs,
6109 sinfo->txrate.flags );
6110#endif //LINKSPEED_DEBUG_ENABLED
6111 }
6112 }
6113 else
6114 {
6115 // report current rate instead of max rate
6116
6117 if (rate_flags & eHAL_TX_RATE_LEGACY)
6118 {
6119 //provide to the UI in units of 100kbps
6120 sinfo->txrate.legacy = myRate;
6121#ifdef LINKSPEED_DEBUG_ENABLED
6122 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6123#endif //LINKSPEED_DEBUG_ENABLED
6124 }
6125 else
6126 {
6127 //must be MCS
6128 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6129 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6130 if (rate_flags & eHAL_TX_RATE_SGI)
6131 {
6132 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6133 }
6134 if (rate_flags & eHAL_TX_RATE_HT40)
6135 {
6136 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6137 }
6138#ifdef LINKSPEED_DEBUG_ENABLED
6139 pr_info("Reporting actual MCS rate %d flags %x\n",
6140 sinfo->txrate.mcs,
6141 sinfo->txrate.flags );
6142#endif //LINKSPEED_DEBUG_ENABLED
6143 }
6144 }
6145 sinfo->filled |= STATION_INFO_TX_BITRATE;
6146
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006147 sinfo->tx_packets =
6148 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6149 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6150 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6151 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6152
6153 sinfo->tx_retries =
6154 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6155 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6156 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6157 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6158
6159 sinfo->tx_failed =
6160 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6161 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6162 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6163 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6164
6165 sinfo->filled |=
6166 STATION_INFO_TX_PACKETS |
6167 STATION_INFO_TX_RETRIES |
6168 STATION_INFO_TX_FAILED;
6169
6170 EXIT();
6171 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006172}
6173
6174static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6175 struct net_device *dev, bool mode, v_SINT_t timeout)
6176{
6177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6178 VOS_STATUS vos_status;
6179
Jeff Johnsone7245742012-09-05 17:12:55 -07006180 ENTER();
6181
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 if (NULL == pAdapter)
6183 {
6184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6185 return -ENODEV;
6186 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006187 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6188 {
6189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6190 "%s:LOGP in Progress. Ignore!!!", __func__);
6191 return -EAGAIN;
6192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006193
6194 /**The get power cmd from the supplicant gets updated by the nl only
6195 *on successful execution of the function call
6196 *we are oppositely mapped w.r.t mode in the driver
6197 **/
6198 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6199
Jeff Johnsone7245742012-09-05 17:12:55 -07006200 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 if (VOS_STATUS_E_FAILURE == vos_status)
6202 {
6203 return -EINVAL;
6204 }
6205 return 0;
6206}
6207
6208
6209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6210static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6211 struct net_device *netdev,
6212 u8 key_index)
6213{
Jeff Johnsone7245742012-09-05 17:12:55 -07006214 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 return 0;
6216}
6217#endif //LINUX_VERSION_CODE
6218
6219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6220static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6221 struct net_device *dev,
6222 struct ieee80211_txq_params *params)
6223{
Jeff Johnsone7245742012-09-05 17:12:55 -07006224 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 return 0;
6226}
6227#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6228static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6229 struct ieee80211_txq_params *params)
6230{
Jeff Johnsone7245742012-09-05 17:12:55 -07006231 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 return 0;
6233}
6234#endif //LINUX_VERSION_CODE
6235
6236static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6237 struct net_device *dev, u8 *mac)
6238{
6239 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006240 VOS_STATUS vos_status;
6241 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006242
Jeff Johnsone7245742012-09-05 17:12:55 -07006243 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6245 {
6246 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6247 return -EINVAL;
6248 }
6249
6250 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6251 {
6252 hddLog( LOGE,
6253 "%s: Wlan Load/Unload is in progress", __func__);
6254 return -EBUSY;
6255 }
6256
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006257 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6258 {
6259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6260 "%s:LOGP in Progress. Ignore!!!", __func__);
6261 return -EAGAIN;
6262 }
6263
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6265#ifdef WLAN_FEATURE_P2P
6266 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6267#endif
6268 )
6269 {
6270 if( NULL == mac )
6271 {
6272 v_U16_t i;
6273 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6274 {
6275 if(pAdapter->aStaInfo[i].isUsed)
6276 {
6277 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6278 hddLog(VOS_TRACE_LEVEL_INFO,
6279 "%s: Delete STA with MAC::"
6280 "%02x:%02x:%02x:%02x:%02x:%02x",
6281 __func__,
6282 macAddr[0], macAddr[1], macAddr[2],
6283 macAddr[3], macAddr[4], macAddr[5]);
6284 hdd_softap_sta_deauth(pAdapter, macAddr);
6285 }
6286 }
6287 }
6288 else
6289 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006290
6291 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6292 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6293 {
6294 hddLog(VOS_TRACE_LEVEL_INFO,
6295 "%s: Skip this DEL STA as this is not used::"
6296 "%02x:%02x:%02x:%02x:%02x:%02x",
6297 __func__,
6298 mac[0], mac[1], mac[2],
6299 mac[3], mac[4], mac[5]);
6300 return -ENOENT;
6301 }
6302
6303 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6304 {
6305 hddLog(VOS_TRACE_LEVEL_INFO,
6306 "%s: Skip this DEL STA as deauth is in progress::"
6307 "%02x:%02x:%02x:%02x:%02x:%02x",
6308 __func__,
6309 mac[0], mac[1], mac[2],
6310 mac[3], mac[4], mac[5]);
6311 return -ENOENT;
6312 }
6313
6314 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6315
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 hddLog(VOS_TRACE_LEVEL_INFO,
6317 "%s: Delete STA with MAC::"
6318 "%02x:%02x:%02x:%02x:%02x:%02x",
6319 __func__,
6320 mac[0], mac[1], mac[2],
6321 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006322
6323 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6324 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6325 {
6326 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6327 hddLog(VOS_TRACE_LEVEL_INFO,
6328 "%s: STA removal failed for ::"
6329 "%02x:%02x:%02x:%02x:%02x:%02x",
6330 __func__,
6331 mac[0], mac[1], mac[2],
6332 mac[3], mac[4], mac[5]);
6333 return -ENOENT;
6334 }
6335
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 }
6337 }
6338
6339 EXIT();
6340
6341 return 0;
6342}
6343
6344static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6345 struct net_device *dev, u8 *mac, struct station_parameters *params)
6346{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006347#ifdef FEATURE_WLAN_TDLS
6348 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6349 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6350 u32 mask, set;
6351 VOS_STATUS status;
Jeff Johnsone7245742012-09-05 17:12:55 -07006352 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006353
6354 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6355 {
6356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6357 "Invalid arguments");
6358 return -EINVAL;
6359 }
6360
6361 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6362 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6363 {
6364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6365 "TDLS Disabled in INI OR not enabled in FW.\
6366 Cannot process TDLS commands \n");
6367 return -ENOTSUPP;
6368 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006369 /* first to check if we reached to maximum supported TDLS peer.
6370 TODO: for now, return -EPERM looks working fine,
6371 but need to check if any other errno fit into this category.*/
6372 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6373 {
6374 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6375 "%s: TDLS Max peer already connected. Request declined. \n",
6376 __func__);
6377 return -EPERM;
6378 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006379
6380 mask = params->sta_flags_mask;
6381
6382 set = params->sta_flags_set;
6383
6384
Lee Hoonkic1262f22013-01-24 21:59:00 -08006385 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6386 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006387
6388 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6389 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6391 "Add TDLS peer");
6392
6393
6394 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6395 pAdapter->sessionId, mac);
6396
6397 if (VOS_STATUS_SUCCESS != status) {
6398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6399 "%s: sme_AddTdlsPeerSta failed!", __func__);
6400 }
6401 }
6402 }
6403#endif
6404
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 return 0;
6406}
6407
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006408
6409#ifdef FEATURE_WLAN_LFR
6410static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006411 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006412{
6413#define MAX_PMKSAIDS_IN_CACHE 8
6414 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006415 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006416 tANI_U32 j=0;
6417 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6418 tHalHandle halHandle;
6419 eHalStatus result;
6420 tANI_U8 BSSIDMatched = 0;
6421
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 ENTER();
6423
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006424 // Validate pAdapter
6425 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6426 {
6427 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6428 return -EINVAL;
6429 }
6430
6431 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6432 {
6433 hddLog( LOGE,
6434 "%s: Wlan Load/Unload is in progress", __func__);
6435 return -EBUSY;
6436 }
6437
6438 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6439 {
6440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6441 "%s:LOGP in Progress. Ignore!!!", __func__);
6442 return -EAGAIN;
6443 }
6444
6445 // Retrieve halHandle
6446 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6447
6448 for (j = 0; j < i; j++)
6449 {
6450 if(vos_mem_compare(PMKIDCache[j].BSSID,
6451 pmksa->bssid, WNI_CFG_BSSID_LEN))
6452 {
6453 /* BSSID matched previous entry. Overwrite it. */
6454 BSSIDMatched = 1;
6455 vos_mem_copy(PMKIDCache[j].BSSID,
6456 pmksa->bssid, WNI_CFG_BSSID_LEN);
6457 vos_mem_copy(PMKIDCache[j].PMKID,
6458 pmksa->pmkid,
6459 CSR_RSN_PMKID_SIZE);
6460 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006461 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006462 dump_bssid(pmksa->bssid);
6463 dump_pmkid(halHandle, pmksa->pmkid);
6464 break;
6465 }
6466 }
6467
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006468 /* Check we compared all entries,if then take the first slot now */
6469 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6470
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006471 if (!BSSIDMatched)
6472 {
6473 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6474 vos_mem_copy(PMKIDCache[i].BSSID,
6475 pmksa->bssid, ETHER_ADDR_LEN);
6476 vos_mem_copy(PMKIDCache[i].PMKID,
6477 pmksa->pmkid,
6478 CSR_RSN_PMKID_SIZE);
6479 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006480 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006481 dump_bssid(pmksa->bssid);
6482 dump_pmkid(halHandle, pmksa->pmkid);
6483 // Increment the HDD Local Cache index
6484 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6485 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6486 }
6487
6488
6489 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6490 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006491 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006492 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006493 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006494 // Finally set the PMKSA ID Cache in CSR
6495 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6496 PMKIDCache,
6497 i );
6498 return 0;
6499}
6500
6501
6502static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006503 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006504{
Jeff Johnsone7245742012-09-05 17:12:55 -07006505 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006506 // TODO: Implement this later.
6507 return 0;
6508}
6509
6510static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6511{
Jeff Johnsone7245742012-09-05 17:12:55 -07006512 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006513 // TODO: Implement this later.
6514 return 0;
6515}
6516#endif
6517
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006518#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6519static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6520 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6521{
6522 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6523 hdd_station_ctx_t *pHddStaCtx;
6524
6525 if (NULL == pAdapter)
6526 {
6527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6528 return -ENODEV;
6529 }
6530
6531 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6532
6533 // Added for debug on reception of Re-assoc Req.
6534 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6535 {
6536 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6537 ftie->ie_len);
6538 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6539 }
6540
6541#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6542 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6543 ftie->ie_len);
6544#endif
6545
6546 // Pass the received FT IEs to SME
6547 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6548 ftie->ie_len);
6549 return 0;
6550}
6551#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006552
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006553#ifdef FEATURE_WLAN_TDLS
6554static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6555 u8 *peer, u8 action_code, u8 dialog_token,
6556 u16 status_code, const u8 *buf, size_t len)
6557{
6558
6559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6560 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006561 u8 peerMac[6];
6562 VOS_STATUS status;
Hoonki Leea34dd892013-02-05 22:56:02 -08006563 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006564
6565 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6566 {
6567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6568 "Invalid arguments");
6569 return -EINVAL;
6570 }
6571
6572 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
6573 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6574 {
6575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6576 "TDLS Disabled in INI OR not enabled in FW.\
6577 Cannot process TDLS commands \n");
6578 return -ENOTSUPP;
6579 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006580
6581 if(SIR_MAC_TDLS_SETUP_REQ == action_code ||
6582 SIR_MAC_TDLS_SETUP_RSP == action_code )
6583 {
6584 if(HDD_MAX_NUM_TDLS_STA == wlan_hdd_tdlsConnectedPeers())
6585 {
6586 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6587 we return error code at 'add_station()'. Hence we have this
6588 check again in addtion to add_station().
6589 Anyway, there is no hard to double-check. */
6590 if(SIR_MAC_TDLS_SETUP_REQ == action_code)
6591 {
6592 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6593 "%s: TDLS Max peer already connected. Request declined. \n",
6594 __func__);
6595 return -EPERM;
6596 }
6597 else
6598 {
6599 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6600 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6601 "%s: TDLS Max peer already connected send response status %d \n",
6602 __func__,status_code);
6603 }
6604 }
6605 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006606 vos_mem_copy( peerMac, peer, 6);
6607
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006608#ifdef WLAN_FEATURE_TDLS_DEBUG
6609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6610 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6611 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6612 action_code, dialog_token, status_code, len);
6613#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006614
Hoonki Leea34dd892013-02-05 22:56:02 -08006615 /*Except teardown responder will not be used so just make 0*/
6616 responder = 0;
6617 if(SIR_MAC_TDLS_TEARDOWN == action_code)
6618 {
6619 responder = wlan_hdd_tdls_get_responder(peerMac);
6620 if(-1 == responder)
6621 {
6622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6623 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6624 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6625 dialog_token, status_code, len);
6626 return -EPERM;
6627 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006628 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006629
6630 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006631 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006632
6633 if (VOS_STATUS_SUCCESS != status) {
6634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6635 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
6636 }
6637
Hoonki Leea34dd892013-02-05 22:56:02 -08006638 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6639 {
6640 wlan_hdd_tdls_set_responder(peerMac, TRUE);
6641 }
6642 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6643 {
6644 wlan_hdd_tdls_set_responder(peerMac, FALSE);
6645 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006646
6647 return 0;
6648}
6649
6650static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6651 u8 *peer, enum nl80211_tdls_operation oper)
6652{
6653 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6654 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006655#ifdef WLAN_FEATURE_TDLS_DEBUG
6656 const char *tdls_oper_str[]= {
6657 "NL80211_TDLS_DISCOVERY_REQ",
6658 "NL80211_TDLS_SETUP",
6659 "NL80211_TDLS_TEARDOWN",
6660 "NL80211_TDLS_ENABLE_LINK",
6661 "NL80211_TDLS_DISABLE_LINK",
6662 "NL80211_TDLS_UNKONW_OPER"};
6663#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006664
6665 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6666 {
6667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6668 "Invalid arguments");
6669 return -EINVAL;
6670 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006671
6672#ifdef WLAN_FEATURE_TDLS_DEBUG
6673 if((int)oper > 4)
6674 oper = 5;
6675
6676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6677 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6678 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6679 tdls_oper_str[(int)oper]);
6680#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006681
6682 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006683 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006684 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006686 "TDLS Disabled in INI OR not enabled in FW.\
6687 Cannot process TDLS commands \n");
6688 return -ENOTSUPP;
6689 }
6690
6691 switch (oper) {
6692 case NL80211_TDLS_ENABLE_LINK:
6693 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006694 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Hoonki Lee387663d2013-02-05 18:08:43 -08006695 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006696 VOS_STATUS status;
6697
6698 if (peer) {
Hoonki Lee387663d2013-02-05 18:08:43 -08006699 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006700
6701 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006702 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006703 __func__, peer[0], peer[1],
6704 peer[2], peer[3],
6705 peer[4], peer[5] );
6706
Hoonki Lee387663d2013-02-05 18:08:43 -08006707 if ( NULL == pTdlsPeer ) {
6708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6709 __func__, peer[0], peer[1],
6710 peer[2], peer[3],
6711 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006712 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006713 }
6714
Hoonki Lee387663d2013-02-05 18:08:43 -08006715 status = WLANTL_ChangeSTAState( pVosContext, pTdlsPeer->staId,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006716 WLANTL_STA_AUTHENTICATED );
6717
Hoonki Leef63df0d2013-01-16 19:29:14 -08006718 //This can fail only if the staId is not registered yet with TL
6719 //return -EINVAL in such case.
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006720 if (0 != status) {
6721 hddLog(VOS_TRACE_LEVEL_ERROR,
6722 "%s: WLANTL_ChangeSTAState failed, returned %d",
6723 __func__, status);
Hoonki Leef63df0d2013-01-16 19:29:14 -08006724 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006725 }
Hoonki Leef63df0d2013-01-16 19:29:14 -08006726
Hoonki Lee387663d2013-02-05 18:08:43 -08006727 wlan_hdd_tdls_set_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Chilam NG571c65a2013-01-19 12:27:36 +05306728
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006729 } else {
6730 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6731 }
6732 }
6733 break;
6734 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006735 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006736 if(NULL != wlan_hdd_tdls_find_peer(peer))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006737 {
6738 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6739 pAdapter->sessionId, peer );
6740 }
6741 else
6742 {
6743 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6744 "%s: TDLS Peer Station doesn't exist \n",__func__);
6745 }
6746 return 0;
6747 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006748 case NL80211_TDLS_TEARDOWN:
6749 case NL80211_TDLS_SETUP:
6750 case NL80211_TDLS_DISCOVERY_REQ:
6751 /* We don't support in-driver setup/teardown/discovery */
6752 return -ENOTSUPP;
6753 default:
6754 return -ENOTSUPP;
6755 }
6756 return 0;
6757}
Chilam NG571c65a2013-01-19 12:27:36 +05306758
6759int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6760 struct net_device *dev, u8 *peer)
6761{
6762 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6763 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6764
6765 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6766 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6767}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006768#endif
6769
Jeff Johnson295189b2012-06-20 16:38:30 -07006770/* cfg80211_ops */
6771static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6772{
6773 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6774 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6775 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6776 .change_station = wlan_hdd_change_station,
6777#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6778 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6779 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6780 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006781#else
6782 .start_ap = wlan_hdd_cfg80211_start_ap,
6783 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6784 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006785#endif
6786 .change_bss = wlan_hdd_cfg80211_change_bss,
6787 .add_key = wlan_hdd_cfg80211_add_key,
6788 .get_key = wlan_hdd_cfg80211_get_key,
6789 .del_key = wlan_hdd_cfg80211_del_key,
6790 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006791#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006793#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 .scan = wlan_hdd_cfg80211_scan,
6795 .connect = wlan_hdd_cfg80211_connect,
6796 .disconnect = wlan_hdd_cfg80211_disconnect,
6797 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6798 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6799 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6800 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6801 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6802#ifdef WLAN_FEATURE_P2P
6803 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6804 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6805 .mgmt_tx = wlan_hdd_action,
6806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6807 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6808 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6809 .set_txq_params = wlan_hdd_set_txq_params,
6810#endif
6811#endif
6812 .get_station = wlan_hdd_cfg80211_get_station,
6813 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6814 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006815 .add_station = wlan_hdd_cfg80211_add_station,
6816#ifdef FEATURE_WLAN_LFR
6817 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6818 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6819 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6820#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006821#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6822 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6823#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006824#ifdef FEATURE_WLAN_TDLS
6825 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6826 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6827#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006828};
6829
6830#endif // CONFIG_CFG80211