blob: ccff3d9c1d421b3d2cef8edb81795c4f76855deb [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));
Jeff Johnson295189b2012-06-20 16:38:30 -07002562#ifdef WLAN_FEATURE_P2P
2563 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2564 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2565#else
2566 pAdapter->device_mode = WLAN_HDD_SOFTAP;
2567#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002568
2569 //Disable BMPS and IMPS if enabled
2570 //before starting Go
2571 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2572 {
2573 if(VOS_STATUS_E_FAILURE ==
2574 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2575 {
2576 //Fail to Exit BMPS
2577 VOS_ASSERT(0);
2578 }
2579 }
2580
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002581 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2582 (pConfig->apRandomBssidEnabled))
2583 {
2584 /* To meet Android requirements create a randomized
2585 MAC address of the form 02:1A:11:Fx:xx:xx */
2586 get_random_bytes(&ndev->dev_addr[3], 3);
2587 ndev->dev_addr[0] = 0x02;
2588 ndev->dev_addr[1] = 0x1A;
2589 ndev->dev_addr[2] = 0x11;
2590 ndev->dev_addr[3] |= 0xF0;
2591 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2592 VOS_MAC_ADDR_SIZE);
2593 pr_info("wlan: Generated HotSpot BSSID "
2594 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2595 ndev->dev_addr[0],
2596 ndev->dev_addr[1],
2597 ndev->dev_addr[2],
2598 ndev->dev_addr[3],
2599 ndev->dev_addr[4],
2600 ndev->dev_addr[5]);
2601 }
2602
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 hdd_set_ap_ops( pAdapter->dev );
2604
2605 status = hdd_init_ap_mode(pAdapter);
2606 if(status != VOS_STATUS_SUCCESS)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_FATAL,
2609 "%s: Error initializing the ap mode", __func__);
2610 return -EINVAL;
2611 }
2612 hdd_set_conparam(1);
2613
Jeff Johnson295189b2012-06-20 16:38:30 -07002614 /*interface type changed update in wiphy structure*/
2615 if(wdev)
2616 {
2617 wdev->iftype = type;
2618 pHddCtx->change_iface = type;
2619 }
2620 else
2621 {
2622 hddLog(VOS_TRACE_LEVEL_ERROR,
2623 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2624 return -EINVAL;
2625 }
2626 goto done;
2627 }
2628
2629 default:
2630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2631 __func__);
2632 return -EOPNOTSUPP;
2633 }
2634 }
2635 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2636#ifdef WLAN_FEATURE_P2P
2637 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2638#endif
2639 )
2640 {
2641 switch(type)
2642 {
2643 case NL80211_IFTYPE_STATION:
2644#ifdef WLAN_FEATURE_P2P
2645 case NL80211_IFTYPE_P2P_CLIENT:
2646#endif
2647 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002648 hdd_stop_adapter( pHddCtx, pAdapter );
2649 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002650 wdev->iftype = type;
2651#ifdef WLAN_FEATURE_P2P
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002652 //Check for sub-string p2p to confirm its a p2p interface
2653 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002654 {
2655 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2656 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2657 }
2658 else
2659 {
2660 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002661 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002662 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002663#endif
2664 hdd_set_conparam(0);
2665 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002666 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2667 hdd_set_station_ops( pAdapter->dev );
2668 status = hdd_init_station_mode( pAdapter );
2669 if( VOS_STATUS_SUCCESS != status )
2670 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002671 /* In case of JB, for P2P-GO, only change interface will be called,
2672 * This is the right place to enable back bmps_imps()
2673 */
2674 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002675 goto done;
2676 case NL80211_IFTYPE_AP:
2677#ifdef WLAN_FEATURE_P2P
2678 case NL80211_IFTYPE_P2P_GO:
2679#endif
2680 wdev->iftype = type;
2681#ifdef WLAN_FEATURE_P2P
2682 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2683 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
2684#endif
2685 goto done;
2686 default:
2687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2688 __func__);
2689 return -EOPNOTSUPP;
2690
2691 }
2692
2693 }
2694 else
2695 {
2696 return -EOPNOTSUPP;
2697 }
2698
2699
2700 if(pRoamProfile)
2701 {
2702 if ( LastBSSType != pRoamProfile->BSSType )
2703 {
2704 /*interface type changed update in wiphy structure*/
2705 wdev->iftype = type;
2706
2707 /*the BSS mode changed, We need to issue disconnect
2708 if connected or in IBSS disconnect state*/
2709 if ( hdd_connGetConnectedBssType(
2710 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2711 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2712 {
2713 /*need to issue a disconnect to CSR.*/
2714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2715 if( eHAL_STATUS_SUCCESS ==
2716 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2717 pAdapter->sessionId,
2718 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2719 {
2720 wait_for_completion_interruptible_timeout(
2721 &pAdapter->disconnect_comp_var,
2722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2723 }
2724 }
2725 }
2726 }
2727
2728done:
2729 /*set bitmask based on updated value*/
2730 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2731#ifdef WLAN_BTAMP_FEATURE
2732 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2733 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2734 {
2735 //we are ok to do AMP
2736 pHddCtx->isAmpAllowed = VOS_TRUE;
2737 }
2738#endif //WLAN_BTAMP_FEATURE
2739 EXIT();
2740 return 0;
2741}
2742
2743static int wlan_hdd_change_station(struct wiphy *wiphy,
2744 struct net_device *dev,
2745 u8 *mac,
2746 struct station_parameters *params)
2747{
2748 VOS_STATUS status = VOS_STATUS_SUCCESS;
2749 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2750 v_MACADDR_t STAMacAddress;
2751
Jeff Johnsone7245742012-09-05 17:12:55 -07002752 ENTER();
2753
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002754 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2755 {
2756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2757 "%s:LOGP in Progress. Ignore!!!", __func__);
2758 return -EAGAIN;
2759 }
2760
Jeff Johnson295189b2012-06-20 16:38:30 -07002761 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2762
2763 if ( ( pAdapter->device_mode == WLAN_HDD_SOFTAP )
2764#ifdef WLAN_FEATURE_P2P
2765 || ( pAdapter->device_mode == WLAN_HDD_P2P_GO )
2766#endif
2767 )
2768 {
2769 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2770 {
2771 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2772 WLANTL_STA_AUTHENTICATED);
2773
2774 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002775 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002776 return -EINVAL;
2777 }
2778 }
2779
Jeff Johnsone7245742012-09-05 17:12:55 -07002780 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002781 return status;
2782}
2783
2784/*
2785 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
2786 * This function is used to get peer station index in IBSS mode
2787 */
2788static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
2789{
2790 u8 idx = 0;
2791 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
2792 ENTER();
2793 memset(temp, 0, VOS_MAC_ADDR_SIZE);
2794 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
2795 {
2796 if ( (0 !=
2797 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
2798 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
2799 temp, VOS_MAC_ADDR_SIZE)
2800 )
2801 {
2802 return idx;
2803 }
2804 }
2805 return idx;
2806}
2807
2808
2809/*
2810 * FUNCTION: wlan_hdd_cfg80211_add_key
2811 * This function is used to initialize the key information
2812 */
2813#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2814static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2815 struct net_device *ndev,
2816 u8 key_index, bool pairwise,
2817 const u8 *mac_addr,
2818 struct key_params *params
2819 )
2820#else
2821static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
2822 struct net_device *ndev,
2823 u8 key_index, const u8 *mac_addr,
2824 struct key_params *params
2825 )
2826#endif
2827{
2828 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2829 tCsrRoamSetKey setKey;
2830 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2831 int status = 0;
2832 v_U32_t roamId= 0xFF;
2833 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2834 hdd_hostapd_state_t *pHostapdState;
2835 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07002836 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002837
2838 ENTER();
2839
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002840 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2841 {
2842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2843 "%s:LOGP in Progress. Ignore!!!", __func__);
2844 return -EAGAIN;
2845 }
2846
Jeff Johnson295189b2012-06-20 16:38:30 -07002847 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2848 __func__,pAdapter->device_mode);
2849
2850 if (CSR_MAX_NUM_KEY <= key_index)
2851 {
2852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
2853 key_index);
2854
2855 return -EINVAL;
2856 }
2857
2858 hddLog(VOS_TRACE_LEVEL_INFO,
2859 "%s: called with key index = %d & key length %d",
2860 __func__, key_index, params->key_len);
2861
2862 /*extract key idx, key len and key*/
2863 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2864 setKey.keyId = key_index;
2865 setKey.keyLength = params->key_len;
2866 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
2867
2868 switch (params->cipher)
2869 {
2870 case WLAN_CIPHER_SUITE_WEP40:
2871 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2872 break;
2873
2874 case WLAN_CIPHER_SUITE_WEP104:
2875 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2876 break;
2877
2878 case WLAN_CIPHER_SUITE_TKIP:
2879 {
2880 u8 *pKey = &setKey.Key[0];
2881 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2882
2883 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2884
2885 /*Supplicant sends the 32bytes key in this order
2886
2887 |--------------|----------|----------|
2888 | Tk1 |TX-MIC | RX Mic |
2889 |--------------|----------|----------|
2890 <---16bytes---><--8bytes--><--8bytes-->
2891
2892 */
2893 /*Sme expects the 32 bytes key to be in the below order
2894
2895 |--------------|----------|----------|
2896 | Tk1 |RX-MIC | TX Mic |
2897 |--------------|----------|----------|
2898 <---16bytes---><--8bytes--><--8bytes-->
2899 */
2900 /* Copy the Temporal Key 1 (TK1) */
2901 vos_mem_copy(pKey, params->key,16);
2902
2903 /*Copy the rx mic first*/
2904 vos_mem_copy(&pKey[16],&params->key[24],8);
2905
2906 /*Copy the tx mic */
2907 vos_mem_copy(&pKey[24],&params->key[16],8);
2908
2909
2910 break;
2911 }
2912
2913 case WLAN_CIPHER_SUITE_CCMP:
2914 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2915 break;
2916
2917#ifdef FEATURE_WLAN_WAPI
2918 case WLAN_CIPHER_SUITE_SMS4:
2919 {
2920 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2921 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
2922 params->key, params->key_len);
2923 return 0;
2924 }
2925#endif
2926#ifdef FEATURE_WLAN_CCX
2927 case WLAN_CIPHER_SUITE_KRK:
2928 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
2929 break;
2930#endif
2931 default:
2932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
2933 __func__, params->cipher);
2934 return -EOPNOTSUPP;
2935 }
2936
2937 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
2938 __func__, setKey.encType);
2939
2940
2941
2942 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2943#ifdef WLAN_FEATURE_P2P
2944 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
2945#endif
2946 )
2947 {
2948
2949
2950 if (
2951#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2952 (!pairwise)
2953#else
2954 (!mac_addr || is_broadcast_ether_addr(mac_addr))
2955#endif
2956 )
2957 {
2958 /* set group key*/
2959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08002960 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 __func__, __LINE__);
2962 setKey.keyDirection = eSIR_RX_ONLY;
2963 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2964 }
2965 else
2966 {
2967 /* set pairwise key*/
2968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2969 "%s- %d: setting pairwise key",
2970 __func__, __LINE__);
2971 setKey.keyDirection = eSIR_TX_RX;
2972 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
2973 }
2974
2975 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2976 if( pHostapdState->bssState == BSS_START )
2977 {
2978 status = WLANSAP_SetKeySta( pVosContext, &setKey);
2979
2980 if ( status != eHAL_STATUS_SUCCESS )
2981 {
2982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2983 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
2984 __LINE__, status );
2985 }
2986 }
2987
2988 /* Saving WEP keys */
2989 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
2990 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
2991 {
2992 //Save the wep key in ap context. Issue setkey after the BSS is started.
2993 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
2994 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
2995 }
2996 else
2997 {
2998 //Save the key in ap context. Issue setkey after the BSS is started.
2999 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3000 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3001 }
3002 }
3003 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3004#ifdef WLAN_FEATURE_P2P
3005 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3006#endif
3007 )
3008 {
3009 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3010 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3011
3012 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3013
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003014 pWextState->roamProfile.Keys.defaultIndex = key_index;
3015
3016
Jeff Johnson295189b2012-06-20 16:38:30 -07003017 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
3018 params->key, params->key_len);
3019
3020 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3021
3022 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3023 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3024 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3025 )
3026 &&
3027 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3028 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3029 )
3030 )
3031 {
3032 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3033 * interface, copy bssid for pairwise key and group macaddr for
3034 * group key initialization*/
3035
3036 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3037
3038 pWextState->roamProfile.negotiatedUCEncryptionType =
3039 pHddStaCtx->conn_info.ucEncryptionType =
3040 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3041 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3042 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3043
3044
3045 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3046 "%s: Negotiated encryption type %d", __func__,
3047 pWextState->roamProfile.negotiatedUCEncryptionType);
3048
3049 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3050 &pWextState->roamProfile, true);
3051 setKey.keyLength = 0;
3052 setKey.keyDirection = eSIR_TX_RX;
3053
3054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3055 if (pairwise)
3056 {
3057#endif
3058 if (mac_addr)
3059 {
3060 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3061 }
3062 else
3063 {
3064 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3065 * and peerMacAddress in case of IBSS*/
3066 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3067 {
3068 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3069 if (HDD_MAX_NUM_IBSS_STA != staidx)
3070 {
3071 vos_mem_copy(setKey.peerMac,
3072 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3073 WNI_CFG_BSSID_LEN);
3074
3075 }
3076 else
3077 {
3078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3079 __func__);
3080 return -EOPNOTSUPP;
3081 }
3082 }
3083 else
3084 {
3085 vos_mem_copy(setKey.peerMac,
3086 &pHddStaCtx->conn_info.bssId[0],
3087 WNI_CFG_BSSID_LEN);
3088 }
3089 }
3090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3091 }
3092 else
3093 {
3094 /* set group key*/
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3096 "%s- %d: setting Group key",
3097 __func__, __LINE__);
3098 setKey.keyDirection = eSIR_RX_ONLY;
3099 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3100 }
3101#endif
3102 }
3103 else if (
3104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3105 (!pairwise)
3106#else
3107 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3108#endif
3109 )
3110 {
3111 /* set group key*/
3112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3113 "%s- %d: setting Group key",
3114 __func__, __LINE__);
3115 setKey.keyDirection = eSIR_RX_ONLY;
3116 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3117 }
3118 else
3119 {
3120 /* set pairwise key*/
3121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3122 "%s- %d: setting pairwise key",
3123 __func__, __LINE__);
3124 setKey.keyDirection = eSIR_TX_RX;
3125 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3126 }
3127
3128 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3129 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3130 __func__, setKey.peerMac[0], setKey.peerMac[1],
3131 setKey.peerMac[2], setKey.peerMac[3],
3132 setKey.peerMac[4], setKey.peerMac[5],
3133 setKey.keyDirection);
3134
3135 vos_status = wlan_hdd_check_ula_done(pAdapter);
3136
3137 if ( vos_status != VOS_STATUS_SUCCESS )
3138 {
3139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3140 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3141 __LINE__, vos_status );
3142
3143 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3144
3145 return -EINVAL;
3146
3147 }
3148
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003149#ifdef WLAN_FEATURE_VOWIFI_11R
3150 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3151 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003152 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303153 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003154 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303155 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003156 }
3157#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003158
3159 /* issue set key request to SME*/
3160 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3161 pAdapter->sessionId, &setKey, &roamId );
3162
3163 if ( 0 != status )
3164 {
3165 hddLog(VOS_TRACE_LEVEL_ERROR,
3166 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3167 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3168 return -EINVAL;
3169 }
3170
3171
3172 /* in case of IBSS as there was no information available about WEP keys during
3173 * IBSS join, group key intialized with NULL key, so re-initialize group key
3174 * with correct value*/
3175 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3176 !( ( IW_AUTH_KEY_MGMT_802_1X
3177 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3178 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3179 )
3180 &&
3181 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3182 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3183 )
3184 )
3185 {
3186 setKey.keyDirection = eSIR_RX_ONLY;
3187 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3188
3189 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3190 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3191 __func__, setKey.peerMac[0], setKey.peerMac[1],
3192 setKey.peerMac[2], setKey.peerMac[3],
3193 setKey.peerMac[4], setKey.peerMac[5],
3194 setKey.keyDirection);
3195
3196 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3197 pAdapter->sessionId, &setKey, &roamId );
3198
3199 if ( 0 != status )
3200 {
3201 hddLog(VOS_TRACE_LEVEL_ERROR,
3202 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3203 __func__, status);
3204 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3205 return -EINVAL;
3206 }
3207 }
3208 }
3209
3210 return 0;
3211}
3212
3213/*
3214 * FUNCTION: wlan_hdd_cfg80211_get_key
3215 * This function is used to get the key information
3216 */
3217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3218static int wlan_hdd_cfg80211_get_key(
3219 struct wiphy *wiphy,
3220 struct net_device *ndev,
3221 u8 key_index, bool pairwise,
3222 const u8 *mac_addr, void *cookie,
3223 void (*callback)(void *cookie, struct key_params*)
3224 )
3225#else
3226static int wlan_hdd_cfg80211_get_key(
3227 struct wiphy *wiphy,
3228 struct net_device *ndev,
3229 u8 key_index, const u8 *mac_addr, void *cookie,
3230 void (*callback)(void *cookie, struct key_params*)
3231 )
3232#endif
3233{
3234 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3235 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3236 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3237 struct key_params params;
3238
3239 ENTER();
3240
3241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3242 __func__,pAdapter->device_mode);
3243
3244 memset(&params, 0, sizeof(params));
3245
3246 if (CSR_MAX_NUM_KEY <= key_index)
3247 {
3248 return -EINVAL;
3249 }
3250
3251 switch(pRoamProfile->EncryptionType.encryptionType[0])
3252 {
3253 case eCSR_ENCRYPT_TYPE_NONE:
3254 params.cipher = IW_AUTH_CIPHER_NONE;
3255 break;
3256
3257 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3258 case eCSR_ENCRYPT_TYPE_WEP40:
3259 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3260 break;
3261
3262 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3263 case eCSR_ENCRYPT_TYPE_WEP104:
3264 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3265 break;
3266
3267 case eCSR_ENCRYPT_TYPE_TKIP:
3268 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3269 break;
3270
3271 case eCSR_ENCRYPT_TYPE_AES:
3272 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3273 break;
3274
3275 default:
3276 params.cipher = IW_AUTH_CIPHER_NONE;
3277 break;
3278 }
3279
3280 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3281 params.seq_len = 0;
3282 params.seq = NULL;
3283 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3284 callback(cookie, &params);
3285 return 0;
3286}
3287
3288/*
3289 * FUNCTION: wlan_hdd_cfg80211_del_key
3290 * This function is used to delete the key information
3291 */
3292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3293static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3294 struct net_device *ndev,
3295 u8 key_index,
3296 bool pairwise,
3297 const u8 *mac_addr
3298 )
3299#else
3300static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3301 struct net_device *ndev,
3302 u8 key_index,
3303 const u8 *mac_addr
3304 )
3305#endif
3306{
3307 int status = 0;
3308
3309 //This code needs to be revisited. There is sme_removeKey API, we should
3310 //plan to use that. After the change to use correct index in setkey,
3311 //it is observed that this is invalidating peer
3312 //key index whenever re-key is done. This is affecting data link.
3313 //It should be ok to ignore del_key.
3314#if 0
3315 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3316 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3317 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3318 tCsrRoamSetKey setKey;
3319 v_U32_t roamId= 0xFF;
3320
3321 ENTER();
3322
3323 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3324 __func__,pAdapter->device_mode);
3325
3326 if (CSR_MAX_NUM_KEY <= key_index)
3327 {
3328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3329 key_index);
3330
3331 return -EINVAL;
3332 }
3333
3334 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3335 setKey.keyId = key_index;
3336
3337 if (mac_addr)
3338 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3339 else
3340 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3341
3342 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3343
3344 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3345#ifdef WLAN_FEATURE_P2P
3346 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
3347#endif
3348 )
3349 {
3350
3351 hdd_hostapd_state_t *pHostapdState =
3352 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3353 if( pHostapdState->bssState == BSS_START)
3354 {
3355 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3356
3357 if ( status != eHAL_STATUS_SUCCESS )
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3361 __LINE__, status );
3362 }
3363 }
3364 }
3365 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3366#ifdef WLAN_FEATURE_P2P
3367 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3368#endif
3369 )
3370 {
3371 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3372
3373 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3374
3375 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3376 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3377 __func__, setKey.peerMac[0], setKey.peerMac[1],
3378 setKey.peerMac[2], setKey.peerMac[3],
3379 setKey.peerMac[4], setKey.peerMac[5]);
3380 if(pAdapter->sessionCtx.station.conn_info.connState ==
3381 eConnectionState_Associated)
3382 {
3383 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3384 pAdapter->sessionId, &setKey, &roamId );
3385
3386 if ( 0 != status )
3387 {
3388 hddLog(VOS_TRACE_LEVEL_ERROR,
3389 "%s: sme_RoamSetKey failure, returned %d",
3390 __func__, status);
3391 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3392 return -EINVAL;
3393 }
3394 }
3395 }
3396#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003397 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003398 return status;
3399}
3400
3401/*
3402 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3403 * This function is used to set the default tx key index
3404 */
3405#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3406static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3407 struct net_device *ndev,
3408 u8 key_index,
3409 bool unicast, bool multicast)
3410#else
3411static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3412 struct net_device *ndev,
3413 u8 key_index)
3414#endif
3415{
3416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3417 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3418 int status = 0;
3419 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3420
3421 ENTER();
3422
3423 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3424 __func__,pAdapter->device_mode, key_index);
3425
3426 if (CSR_MAX_NUM_KEY <= key_index)
3427 {
3428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3429 key_index);
3430
3431 return -EINVAL;
3432 }
3433
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003434 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3435 {
3436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3437 "%s:LOGP in Progress. Ignore!!!", __func__);
3438 return -EAGAIN;
3439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003440
3441 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3442#ifdef WLAN_FEATURE_P2P
3443 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
3444#endif
3445 )
3446 {
3447 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3448 (eCSR_ENCRYPT_TYPE_TKIP !=
3449 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3450 (eCSR_ENCRYPT_TYPE_AES !=
3451 pWextState->roamProfile.EncryptionType.encryptionType[0])
3452 )
3453 {
3454 /* if default key index is not same as previous one,
3455 * then update the default key index */
3456
3457 tCsrRoamSetKey setKey;
3458 v_U32_t roamId= 0xFF;
3459 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3460
3461 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3462 __func__, key_index);
3463
3464 Keys->defaultIndex = (u8)key_index;
3465 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3466 setKey.keyId = key_index;
3467 setKey.keyLength = Keys->KeyLength[key_index];
3468
3469 vos_mem_copy(&setKey.Key[0],
3470 &Keys->KeyMaterial[key_index][0],
3471 Keys->KeyLength[key_index]);
3472
3473 setKey.keyDirection = eSIR_TX_ONLY;
3474
3475 vos_mem_copy(setKey.peerMac,
3476 &pHddStaCtx->conn_info.bssId[0],
3477 WNI_CFG_BSSID_LEN);
3478
3479 setKey.encType =
3480 pWextState->roamProfile.EncryptionType.encryptionType[0];
3481
3482 /* issue set key request */
3483 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3484 pAdapter->sessionId, &setKey, &roamId );
3485
3486 if ( 0 != status )
3487 {
3488 hddLog(VOS_TRACE_LEVEL_ERROR,
3489 "%s: sme_RoamSetKey failed, returned %d", __func__,
3490 status);
3491 return -EINVAL;
3492 }
3493 }
3494 }
3495
3496 /* In SoftAp mode setting key direction for default mode */
3497 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3498 {
3499 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3500 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3501 (eCSR_ENCRYPT_TYPE_AES !=
3502 pWextState->roamProfile.EncryptionType.encryptionType[0])
3503 )
3504 {
3505 /* Saving key direction for default key index to TX default */
3506 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3507 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3508 }
3509 }
3510
3511 return status;
3512}
3513
Jeff Johnson295189b2012-06-20 16:38:30 -07003514/*
3515 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3516 * This function is used to inform the BSS details to nl80211 interface.
3517 */
3518static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3519 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3520{
3521 struct net_device *dev = pAdapter->dev;
3522 struct wireless_dev *wdev = dev->ieee80211_ptr;
3523 struct wiphy *wiphy = wdev->wiphy;
3524 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3525 int chan_no;
3526 int ie_length;
3527 const char *ie;
3528 unsigned int freq;
3529 struct ieee80211_channel *chan;
3530 int rssi = 0;
3531 struct cfg80211_bss *bss = NULL;
3532
3533 ENTER();
3534
3535 if( NULL == pBssDesc )
3536 {
3537 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3538 return bss;
3539 }
3540
3541 chan_no = pBssDesc->channelId;
3542 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3543 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3544
3545 if( NULL == ie )
3546 {
3547 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3548 return bss;
3549 }
3550
3551#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3552 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3553 {
3554 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3555 }
3556 else
3557 {
3558 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3559 }
3560#else
3561 freq = ieee80211_channel_to_frequency(chan_no);
3562#endif
3563
3564 chan = __ieee80211_get_channel(wiphy, freq);
3565
3566 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3567 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3568 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3569 if (bss == NULL)
3570 {
3571 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3572
3573 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3574 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3575 pBssDesc->capabilityInfo,
3576 pBssDesc->beaconInterval, ie, ie_length,
3577 rssi, GFP_KERNEL ));
3578}
3579 else
3580 {
3581 return bss;
3582 }
3583}
3584
3585
3586
3587/*
3588 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3589 * This function is used to inform the BSS details to nl80211 interface.
3590 */
3591struct cfg80211_bss*
3592wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3593 tSirBssDescription *bss_desc
3594 )
3595{
3596 /*
3597 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3598 already exists in bss data base of cfg80211 for that particular BSS ID.
3599 Using cfg80211_inform_bss_frame to update the bss entry instead of
3600 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3601 now there is no possibility to get the mgmt(probe response) frame from PE,
3602 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3603 cfg80211_inform_bss_frame.
3604 */
3605 struct net_device *dev = pAdapter->dev;
3606 struct wireless_dev *wdev = dev->ieee80211_ptr;
3607 struct wiphy *wiphy = wdev->wiphy;
3608 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003609#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3610 qcom_ie_age *qie_age = NULL;
3611 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3612#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003613 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003614#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003615 const char *ie =
3616 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3617 unsigned int freq;
3618 struct ieee80211_channel *chan;
3619 struct ieee80211_mgmt *mgmt =
3620 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3621 struct cfg80211_bss *bss_status = NULL;
3622 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3623 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003624#ifdef WLAN_OPEN_SOURCE
3625 struct timespec ts;
3626#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003627
3628 ENTER();
3629
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003630 if (!mgmt)
3631 return NULL;
3632
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003634
3635#ifdef WLAN_OPEN_SOURCE
3636 /* Android does not want the timestamp from the frame.
3637 Instead it wants a monotonic increasing value */
3638 get_monotonic_boottime(&ts);
3639 mgmt->u.probe_resp.timestamp =
3640 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3641#else
3642 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003643 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3644 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003645
3646#endif
3647
Jeff Johnson295189b2012-06-20 16:38:30 -07003648 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3649 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003650
3651#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3652 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3653 /* Assuming this is the last IE, copy at the end */
3654 ie_length -=sizeof(qcom_ie_age);
3655 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3656 qie_age->element_id = QCOM_VENDOR_IE_ID;
3657 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3658 qie_age->oui_1 = QCOM_OUI1;
3659 qie_age->oui_2 = QCOM_OUI2;
3660 qie_age->oui_3 = QCOM_OUI3;
3661 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3662 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3663#endif
3664
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3666
3667 mgmt->frame_control |=
3668 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3669
3670#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3671 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3672 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3673 {
3674 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3675 }
3676 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3677 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3678
3679 {
3680 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3681 }
3682 else
3683 {
3684 kfree(mgmt);
3685 return NULL;
3686 }
3687#else
3688 freq = ieee80211_channel_to_frequency(chan_no);
3689#endif
3690 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003691 /*when the band is changed on the fly using the GUI, three things are done
3692 * 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)
3693 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3694 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3695 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3696 * and discards the channels correponding to previous band and calls back with zero bss results.
3697 * 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
3698 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3699 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3700 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3701 * So drop the bss and continue to next bss.
3702 */
3703 if(chan == NULL)
3704 {
3705 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3706 return NULL;
3707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003708 /*To keep the rssi icon of the connected AP in the scan window
3709 *and the rssi icon of the wireless networks in sync
3710 * */
3711 if (( eConnectionState_Associated ==
3712 pAdapter->sessionCtx.station.conn_info.connState ) &&
3713 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3714 pAdapter->sessionCtx.station.conn_info.bssId,
3715 WNI_CFG_BSSID_LEN)))
3716 {
3717 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3718 rssi = (pAdapter->rssi * 100);
3719 }
3720 else
3721 {
3722 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3723 }
3724
3725 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3726 frame_len, rssi, GFP_KERNEL);
3727 kfree(mgmt);
3728 return bss_status;
3729}
3730
3731/*
3732 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3733 * This function is used to update the BSS data base of CFG8011
3734 */
3735struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3736 tCsrRoamInfo *pRoamInfo
3737 )
3738{
3739 tCsrRoamConnectedProfile roamProfile;
3740 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3741 struct cfg80211_bss *bss = NULL;
3742
3743 ENTER();
3744
3745 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3746 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3747
3748 if (NULL != roamProfile.pBssDesc)
3749 {
3750 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
3751 &roamProfile);
3752
3753 if (NULL == bss)
3754 {
3755 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3756 __func__);
3757 }
3758
3759 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3760 }
3761 else
3762 {
3763 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3764 __func__);
3765 }
3766 return bss;
3767}
3768
3769/*
3770 * FUNCTION: wlan_hdd_cfg80211_update_bss
3771 */
3772static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3773 hdd_adapter_t *pAdapter
3774 )
3775{
3776 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3777 tCsrScanResultInfo *pScanResult;
3778 eHalStatus status = 0;
3779 tScanResultHandle pResult;
3780 struct cfg80211_bss *bss_status = NULL;
3781
3782 ENTER();
3783
3784 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3785 {
3786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3787 return -EAGAIN;
3788 }
3789
3790 /*
3791 * start getting scan results and populate cgf80211 BSS database
3792 */
3793 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3794
3795 /* no scan results */
3796 if (NULL == pResult)
3797 {
3798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3799 return status;
3800 }
3801
3802 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3803
3804 while (pScanResult)
3805 {
3806 /*
3807 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3808 * entry already exists in bss data base of cfg80211 for that
3809 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3810 * bss entry instead of cfg80211_inform_bss, But this call expects
3811 * mgmt packet as input. As of now there is no possibility to get
3812 * the mgmt(probe response) frame from PE, converting bss_desc to
3813 * ieee80211_mgmt(probe response) and passing to c
3814 * fg80211_inform_bss_frame.
3815 * */
3816
3817 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3818 &pScanResult->BssDescriptor);
3819
3820
3821 if (NULL == bss_status)
3822 {
3823 hddLog(VOS_TRACE_LEVEL_INFO,
3824 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3825 }
3826 else
3827 {
3828 cfg80211_put_bss(bss_status);
3829 }
3830
3831 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3832 }
3833
3834 sme_ScanResultPurge(hHal, pResult);
3835
3836 return 0;
3837}
3838
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003839void
3840hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3841{
3842 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003843 "%02X:%02X:%02X:%02X:%02X:%02X\n",
3844 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
3845 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003846} /****** end hddPrintMacAddr() ******/
3847
3848void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003849hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003850{
3851 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003852 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
3853 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
3854 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
3855 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003856} /****** end hddPrintPmkId() ******/
3857
3858//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
3859//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
3860
3861//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
3862//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
3863
3864#define dump_bssid(bssid) \
3865 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003866 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
3867 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
3868 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003869 }
3870
3871#define dump_pmkid(pMac, pmkid) \
3872 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07003873 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
3874 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
3875 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003876 }
3877
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07003878#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003879/*
3880 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
3881 * This function is used to notify the supplicant of a new PMKSA candidate.
3882 */
3883int wlan_hdd_cfg80211_pmksa_candidate_notify(
3884 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
3885 int index, bool preauth )
3886{
Jeff Johnsone7245742012-09-05 17:12:55 -07003887#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003888 struct net_device *dev = pAdapter->dev;
3889
3890 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07003891 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003892
3893 if( NULL == pRoamInfo )
3894 {
3895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
3896 return -EINVAL;
3897 }
3898
3899 dump_bssid(pRoamInfo->bssid);
3900 cfg80211_pmksa_candidate_notify(dev, index,
3901 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07003902#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003903 return 0;
3904}
3905#endif //FEATURE_WLAN_LFR
3906
Jeff Johnson295189b2012-06-20 16:38:30 -07003907/*
3908 * FUNCTION: hdd_cfg80211_scan_done_callback
3909 * scanning callback function, called after finishing scan
3910 *
3911 */
3912static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
3913 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
3914{
3915 struct net_device *dev = (struct net_device *) pContext;
3916 //struct wireless_dev *wdev = dev->ieee80211_ptr;
3917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003918 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3919 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07003920 struct cfg80211_scan_request *req = NULL;
3921 int ret = 0;
3922
3923 ENTER();
3924
3925 hddLog(VOS_TRACE_LEVEL_INFO,
3926 "%s called with halHandle = %p, pContext = %p,"
3927 "scanID = %d, returned status = %d\n",
3928 __func__, halHandle, pContext, (int) scanId, (int) status);
3929
3930 //Block on scan req completion variable. Can't wait forever though.
3931 ret = wait_for_completion_interruptible_timeout(
3932 &pScanInfo->scan_req_completion_event,
3933 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
3934 if (!ret)
3935 {
3936 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003937 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 }
3939
3940 if(pScanInfo->mScanPending != VOS_TRUE)
3941 {
3942 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07003943 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003944 }
3945
3946 /* Check the scanId */
3947 if (pScanInfo->scanId != scanId)
3948 {
3949 hddLog(VOS_TRACE_LEVEL_INFO,
3950 "%s called with mismatched scanId pScanInfo->scanId = %d "
3951 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
3952 (int) scanId);
3953 }
3954
Jeff Johnson295189b2012-06-20 16:38:30 -07003955 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
3956 pAdapter);
3957
3958 if (0 > ret)
3959 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
3960
3961
3962 /* If any client wait scan result through WEXT
3963 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003964 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07003965 {
3966 /* The other scan request waiting for current scan finish
3967 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003968 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003969 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003970 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 }
3972 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003973 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07003974 {
3975 struct net_device *dev = pAdapter->dev;
3976 union iwreq_data wrqu;
3977 int we_event;
3978 char *msg;
3979
3980 memset(&wrqu, '\0', sizeof(wrqu));
3981 we_event = SIOCGIWSCAN;
3982 msg = NULL;
3983 wireless_send_event(dev, we_event, &wrqu, msg);
3984 }
3985 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07003986 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003987
3988 /* Get the Scan Req */
3989 req = pAdapter->request;
3990
3991 if (!req)
3992 {
3993 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07003994 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003995 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07003996 }
3997
3998 /*
3999 * setting up 0, just in case.
4000 */
4001 req->n_ssids = 0;
4002 req->n_channels = 0;
4003 req->ie = 0;
4004
Jeff Johnson295189b2012-06-20 16:38:30 -07004005 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004006 /* Scan is no longer pending */
4007 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004008
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004009 /*
4010 * cfg80211_scan_done informing NL80211 about completion
4011 * of scanning
4012 */
4013 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004014 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004015
Jeff Johnsone7245742012-09-05 17:12:55 -07004016allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004017 /* release the wake lock at the end of the scan*/
4018 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004019
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004020 /* Acquire wakelock to handle the case where APP's tries to suspend
4021 * immediatly after the driver gets connect request(i.e after scan)
4022 * from supplicant, this result in app's is suspending and not able
4023 * to process the connect request to AP */
4024 hdd_allow_suspend_timeout(100);
4025
Jeff Johnson295189b2012-06-20 16:38:30 -07004026 EXIT();
4027 return 0;
4028}
4029
4030/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004031 * FUNCTION: hdd_isScanAllowed
4032 * Go through each adapter and check if scan allowed
4033 *
4034 */
4035v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4036{
4037 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4038 hdd_station_ctx_t *pHddStaCtx = NULL;
4039 hdd_adapter_t *pAdapter = NULL;
4040 VOS_STATUS status = 0;
4041 v_U8_t staId = 0;
4042 v_U8_t *staMac = NULL;
4043
4044 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4045
4046 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4047 {
4048 pAdapter = pAdapterNode->pAdapter;
4049
4050 if( pAdapter )
4051 {
4052 hddLog(VOS_TRACE_LEVEL_INFO,
4053 "%s: Adapter with device mode %d exists",
4054 __func__, pAdapter->device_mode);
4055 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4056 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4057 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4058 {
4059 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4060 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4061 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4062 {
4063 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4064 hddLog(VOS_TRACE_LEVEL_ERROR,
4065 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4066 "middle of WPS/EAPOL exchange.", __func__,
4067 staMac[0], staMac[1], staMac[2],
4068 staMac[3], staMac[4], staMac[5]);
4069 return VOS_FALSE;
4070 }
4071 }
4072 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4073 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4074 {
4075 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4076 {
4077 if ((pAdapter->aStaInfo[staId].isUsed) &&
4078 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4079 {
4080 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4081
4082 hddLog(VOS_TRACE_LEVEL_ERROR,
4083 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4084 "middle of WPS/EAPOL exchange.", __func__,
4085 staMac[0], staMac[1], staMac[2],
4086 staMac[3], staMac[4], staMac[5]);
4087 return VOS_FALSE;
4088 }
4089 }
4090 }
4091 }
4092 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4093 pAdapterNode = pNext;
4094 }
4095 hddLog(VOS_TRACE_LEVEL_INFO,
4096 "%s: Scan allowed", __func__);
4097 return VOS_TRUE;
4098}
4099
4100/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004101 * FUNCTION: wlan_hdd_cfg80211_scan
4102 * this scan respond to scan trigger and update cfg80211 scan database
4103 * later, scan dump command can be used to recieve scan results
4104 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004105int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4106#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4107 struct net_device *dev,
4108#endif
4109 struct cfg80211_scan_request *request)
4110{
4111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4112 struct net_device *dev = request->wdev->netdev;
4113#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4115 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4116 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4117 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4118 tCsrScanRequest scanRequest;
4119 tANI_U8 *channelList = NULL, i;
4120 v_U32_t scanId = 0;
4121 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004122 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004123#ifdef WLAN_FEATURE_P2P
4124 v_U8_t* pP2pIe = NULL;
4125#endif
4126
4127 ENTER();
4128
4129 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4130 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004131
4132 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
4133 (eConnectionState_Connecting ==
4134 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) )
4135 {
4136 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004137 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4138 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004139 return -EBUSY;
4140 }
4141
Jeff Johnson295189b2012-06-20 16:38:30 -07004142#ifdef WLAN_BTAMP_FEATURE
4143 //Scan not supported when AMP traffic is on.
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004144 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07004145 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004146 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 "%s: No scanning when AMP is on", __func__);
4148 return -EOPNOTSUPP;
4149 }
4150#endif
4151 //Scan on any other interface is not supported.
4152 if( pAdapter->device_mode == WLAN_HDD_SOFTAP )
4153 {
4154 hddLog(VOS_TRACE_LEVEL_ERROR,
4155 "%s: Not scanning on device_mode = %d",
4156 __func__, pAdapter->device_mode);
4157 return -EOPNOTSUPP;
4158 }
4159
4160 if (TRUE == pScanInfo->mScanPending)
4161 {
4162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
4163 return -EBUSY;
4164 }
4165
4166 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4167 {
4168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4169 "%s:LOGP in Progress. Ignore!!!", __func__);
4170 return -EAGAIN;
4171 }
4172
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004173 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4174 {
4175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4176 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4177 return -EAGAIN;
4178 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004179 //Don't Allow Scan and return busy if Remain On
4180 //Channel and action frame is pending
4181 //Otherwise Cancel Remain On Channel and allow Scan
4182 //If no action frame pending
4183 if(0 != wlan_hdd_check_remain_on_channel(pAdapter))
4184 {
4185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4186 return -EBUSY;
4187 }
4188
Jeff Johnson295189b2012-06-20 16:38:30 -07004189 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4190 {
4191 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004192 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004193 return -EAGAIN;
4194 }
4195 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4196 {
4197 hddLog(VOS_TRACE_LEVEL_WARN,
4198 "%s: MAX TM Level Scan not allowed", __func__);
4199 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4200 return -EBUSY;
4201 }
4202 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4203
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004204 /* Check if scan is allowed at this point of time.
4205 */
4206 if (!hdd_isScanAllowed(pHddCtx))
4207 {
4208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4209 return -EBUSY;
4210 }
4211
Jeff Johnson295189b2012-06-20 16:38:30 -07004212 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4213
4214 if (NULL != request)
4215 {
4216 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4217 (int)request->n_ssids);
4218
4219 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4220 * Becasue of this, driver is assuming that this is not wildcard scan and so
4221 * is not aging out the scan results.
4222 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004223 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004224 {
4225 request->n_ssids = 0;
4226 }
4227
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004228 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004229 {
4230 tCsrSSIDInfo *SsidInfo;
4231 int j;
4232 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4233 /* Allocate num_ssid tCsrSSIDInfo structure */
4234 SsidInfo = scanRequest.SSIDs.SSIDList =
4235 ( tCsrSSIDInfo *)vos_mem_malloc(
4236 request->n_ssids*sizeof(tCsrSSIDInfo));
4237
4238 if(NULL == scanRequest.SSIDs.SSIDList)
4239 {
4240 hddLog(VOS_TRACE_LEVEL_ERROR,
4241 "memory alloc failed SSIDInfo buffer");
4242 return -ENOMEM;
4243 }
4244
4245 /* copy all the ssid's and their length */
4246 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4247 {
4248 /* get the ssid length */
4249 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4250 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4251 SsidInfo->SSID.length);
4252 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4253 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4254 j, SsidInfo->SSID.ssId);
4255 }
4256 /* set the scan type to active */
4257 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4258 }
4259 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4260 {
4261 /* set the scan type to active */
4262 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4263 }
4264 else
4265 {
4266 /*Set the scan type to default type, in this case it is ACTIVE*/
4267 scanRequest.scanType = pScanInfo->scan_mode;
4268 }
4269 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4270 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4271 }
4272 else
4273 {
4274 /* set the scan type to active */
4275 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4276 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4277
4278 /* set min and max channel time to zero */
4279 scanRequest.minChnTime = 0;
4280 scanRequest.maxChnTime = 0;
4281 }
4282
4283 /* set BSSType to default type */
4284 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4285
4286 /*TODO: scan the requested channels only*/
4287
4288 /*Right now scanning all the channels */
4289 if( request )
4290 {
4291 if( request->n_channels )
4292 {
4293 channelList = vos_mem_malloc( request->n_channels );
4294 if( NULL == channelList )
4295 {
4296 status = -ENOMEM;
4297 goto free_mem;
4298 }
4299
4300 for( i = 0 ; i < request->n_channels ; i++ )
4301 channelList[i] = request->channels[i]->hw_value;
4302 }
4303
4304 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4305 scanRequest.ChannelInfo.ChannelList = channelList;
4306
4307 /* set requestType to full scan */
4308 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004309
4310 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4311 * search (Flush on both full scan and social scan but not on single
4312 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4313 */
4314
4315 /* Supplicant does single channel scan after 8-way handshake
4316 * and in that case driver shoudnt flush scan results. If
4317 * driver flushes the scan results here and unfortunately if
4318 * the AP doesnt respond to our probe req then association
4319 * fails which is not desired
4320 */
4321
4322 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4323 {
4324 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4325 pAdapter->sessionId );
4326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004327
4328 if( request->ie_len )
4329 {
4330 /* save this for future association (join requires this) */
4331 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4332 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4333 pScanInfo->scanAddIE.length = request->ie_len;
4334
4335 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004336 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4337 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004338 )
4339 {
4340 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4341 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4342 }
4343
4344 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4345 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4346
4347#ifdef WLAN_FEATURE_P2P
4348 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4349 request->ie_len);
4350 if (pP2pIe != NULL)
4351 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004352#ifdef WLAN_FEATURE_P2P_DEBUG
4353 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4354 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4355 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4356 {
4357 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4358 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4359 "Go nego completed to Connection is started");
4360 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4361 "for 8way Handshake");
4362 }
4363 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4364 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4365 {
4366 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4367 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4368 "Disconnected state to Connection is started");
4369 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4370 "for 4way Handshake");
4371 }
4372#endif
4373
Jeff Johnsone7245742012-09-05 17:12:55 -07004374 /* no_cck will be set during p2p find to disable 11b rates */
4375 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004377 hddLog(VOS_TRACE_LEVEL_INFO,
4378 "%s: This is a P2P Search", __func__);
4379 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004380
Jeff Johnsone7245742012-09-05 17:12:55 -07004381 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4382 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004383 /* set requestType to P2P Discovery */
4384 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004385 }
4386
4387 /*
4388 Skip Dfs Channel in case of P2P Search
4389 if it is set in ini file
4390 */
4391 if(cfg_param->skipDfsChnlInP2pSearch)
4392 {
4393 scanRequest.skipDfsChnlInP2pSearch = 1;
4394 }
4395 else
4396 {
4397 scanRequest.skipDfsChnlInP2pSearch = 0;
4398 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004399
Jeff Johnson295189b2012-06-20 16:38:30 -07004400 }
4401 }
4402#endif
4403 }
4404 }
4405
4406 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4407
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004408 /* acquire the wakelock to avoid the apps suspend during the scan. To
4409 * address the following issues.
4410 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4411 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4412 * for long time, this result in apps running at full power for long time.
4413 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4414 * be stuck in full power because of resume BMPS
4415 */
4416 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004417
4418 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004419 pAdapter->sessionId, &scanRequest, &scanId,
4420 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004421
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 if (eHAL_STATUS_SUCCESS != status)
4423 {
4424 hddLog(VOS_TRACE_LEVEL_ERROR,
4425 "%s: sme_ScanRequest returned error %d", __func__, status);
4426 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004427 if(eHAL_STATUS_RESOURCES == status)
4428 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004429 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 -07004430 status = -EBUSY;
4431 } else {
4432 status = -EIO;
4433 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004434 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004435 goto free_mem;
4436 }
4437
4438 pScanInfo->mScanPending = TRUE;
4439 pAdapter->request = request;
4440 pScanInfo->scanId = scanId;
4441
4442 complete(&pScanInfo->scan_req_completion_event);
4443
4444free_mem:
4445 if( scanRequest.SSIDs.SSIDList )
4446 {
4447 vos_mem_free(scanRequest.SSIDs.SSIDList);
4448 }
4449
4450 if( channelList )
4451 vos_mem_free( channelList );
4452
4453 EXIT();
4454
4455 return status;
4456}
4457
4458/*
4459 * FUNCTION: wlan_hdd_cfg80211_connect_start
4460 * This function is used to start the association process
4461 */
4462int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004463 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004464{
4465 int status = 0;
4466 hdd_wext_state_t *pWextState;
4467 v_U32_t roamId;
4468 tCsrRoamProfile *pRoamProfile;
4469 eMib_dot11DesiredBssType connectedBssType;
4470 eCsrAuthType RSNAuthType;
4471
4472 ENTER();
4473
4474 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4475
4476 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4477 {
4478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4479 return -EINVAL;
4480 }
4481
4482 pRoamProfile = &pWextState->roamProfile;
4483
4484 if (pRoamProfile)
4485 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004486 int ret = 0;
4487 hdd_station_ctx_t *pHddStaCtx;
4488 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4489 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4490
4491 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4492 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4493 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004494 {
4495 /* Issue disconnect to CSR */
4496 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4497 if( eHAL_STATUS_SUCCESS ==
4498 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4499 pAdapter->sessionId,
4500 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4501 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004502 ret = wait_for_completion_interruptible_timeout(
4503 &pAdapter->disconnect_comp_var,
4504 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4505 if (0 == ret)
4506 {
4507 VOS_ASSERT(0);
4508 }
4509 }
4510 }
4511 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4512 {
4513 ret = wait_for_completion_interruptible_timeout(
4514 &pAdapter->disconnect_comp_var,
4515 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4516 if (0 == ret)
4517 {
4518 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004519 }
4520 }
4521
4522 if (HDD_WMM_USER_MODE_NO_QOS ==
4523 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4524 {
4525 /*QoS not enabled in cfg file*/
4526 pRoamProfile->uapsd_mask = 0;
4527 }
4528 else
4529 {
4530 /*QoS enabled, update uapsd mask from cfg file*/
4531 pRoamProfile->uapsd_mask =
4532 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4533 }
4534
4535 pRoamProfile->SSIDs.numOfSSIDs = 1;
4536 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4537 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4538 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4539 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4540 ssid, ssid_len);
4541
4542 if (bssid)
4543 {
4544 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4545 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4546 WNI_CFG_BSSID_LEN);
4547 /* Save BSSID in seperate variable as well, as RoamProfile
4548 BSSID is getting zeroed out in the association process. And in
4549 case of join failure we should send valid BSSID to supplicant
4550 */
4551 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4552 WNI_CFG_BSSID_LEN);
4553 }
4554
4555 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4556 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4557 {
4558 /*set gen ie*/
4559 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4560 /*set auth*/
4561 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4562 }
4563 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4564 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4565 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4566 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4567 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4568 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4569 )
4570 {
4571 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4572 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4573 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4574 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4575 eCSR_AUTH_TYPE_AUTOSWITCH;
4576 pWextState->roamProfile.AuthType.authType[0] =
4577 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4578 }
4579#ifdef FEATURE_WLAN_WAPI
4580 if (pAdapter->wapi_info.nWapiMode)
4581 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004582 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 switch (pAdapter->wapi_info.wapiAuthMode)
4584 {
4585 case WAPI_AUTH_MODE_PSK:
4586 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004587 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004588 pAdapter->wapi_info.wapiAuthMode);
4589 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4590 break;
4591 }
4592 case WAPI_AUTH_MODE_CERT:
4593 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004594 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004595 pAdapter->wapi_info.wapiAuthMode);
4596 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4597 break;
4598 }
4599 } // End of switch
4600 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4601 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4602 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004603 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004604 pRoamProfile->AuthType.numEntries = 1;
4605 pRoamProfile->EncryptionType.numEntries = 1;
4606 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4607 pRoamProfile->mcEncryptionType.numEntries = 1;
4608 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4609 }
4610 }
4611#endif /* FEATURE_WLAN_WAPI */
4612 pRoamProfile->csrPersona = pAdapter->device_mode;
4613
Jeff Johnson32d95a32012-09-10 13:15:23 -07004614 if( operatingChannel )
4615 {
4616 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4617 pRoamProfile->ChannelInfo.numOfChannels = 1;
4618 }
4619
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004620 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4621 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4622 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4623 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004624 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4625 */
4626 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4627 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4628 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004629
Jeff Johnson295189b2012-06-20 16:38:30 -07004630 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4631 pAdapter->sessionId, pRoamProfile, &roamId);
4632
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004633 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304634 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4635
4636 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4638 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4639 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304640 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004641 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304642 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004643
4644 pRoamProfile->ChannelInfo.ChannelList = NULL;
4645 pRoamProfile->ChannelInfo.numOfChannels = 0;
4646
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 }
4648 else
4649 {
4650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4651 return -EINVAL;
4652 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004653 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 return status;
4655}
4656
4657/*
4658 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4659 * This function is used to set the authentication type (OPEN/SHARED).
4660 *
4661 */
4662static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4663 enum nl80211_auth_type auth_type)
4664{
4665 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4667
4668 ENTER();
4669
4670 /*set authentication type*/
4671 switch (auth_type)
4672 {
4673 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4674 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004675#ifdef WLAN_FEATURE_VOWIFI_11R
4676 case NL80211_AUTHTYPE_FT:
4677#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 hddLog(VOS_TRACE_LEVEL_INFO,
4679 "%s: set authentication type to OPEN", __func__);
4680 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4681 break;
4682
4683 case NL80211_AUTHTYPE_SHARED_KEY:
4684 hddLog(VOS_TRACE_LEVEL_INFO,
4685 "%s: set authentication type to SHARED", __func__);
4686 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4687 break;
4688#ifdef FEATURE_WLAN_CCX
4689 case NL80211_AUTHTYPE_NETWORK_EAP:
4690 hddLog(VOS_TRACE_LEVEL_INFO,
4691 "%s: set authentication type to CCKM WPA", __func__);
4692 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4693 break;
4694#endif
4695
4696
4697 default:
4698 hddLog(VOS_TRACE_LEVEL_ERROR,
4699 "%s: Unsupported authentication type %d", __func__,
4700 auth_type);
4701 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4702 return -EINVAL;
4703 }
4704
4705 pWextState->roamProfile.AuthType.authType[0] =
4706 pHddStaCtx->conn_info.authType;
4707 return 0;
4708}
4709
4710/*
4711 * FUNCTION: wlan_hdd_set_akm_suite
4712 * This function is used to set the key mgmt type(PSK/8021x).
4713 *
4714 */
4715static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4716 u32 key_mgmt
4717 )
4718{
4719 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4720 ENTER();
4721
4722 /*set key mgmt type*/
4723 switch(key_mgmt)
4724 {
4725 case WLAN_AKM_SUITE_PSK:
4726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
4727 __func__);
4728 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4729 break;
4730
4731 case WLAN_AKM_SUITE_8021X:
4732 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
4733 __func__);
4734 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4735 break;
4736#ifdef FEATURE_WLAN_CCX
4737#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4738#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4739 case WLAN_AKM_SUITE_CCKM:
4740 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4741 __func__);
4742 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4743 break;
4744#endif
4745
4746 default:
4747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
4748 __func__, key_mgmt);
4749 return -EINVAL;
4750
4751 }
4752 return 0;
4753}
4754
4755/*
4756 * FUNCTION: wlan_hdd_cfg80211_set_cipher
4757 * This function is used to set the encryption type
4758 * (NONE/WEP40/WEP104/TKIP/CCMP).
4759 */
4760static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4761 u32 cipher,
4762 bool ucast
4763 )
4764{
4765 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4766 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4768
4769 ENTER();
4770
4771 if (!cipher)
4772 {
4773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
4774 __func__, cipher);
4775 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4776 }
4777 else
4778 {
4779
4780 /*set encryption method*/
4781 switch (cipher)
4782 {
4783 case IW_AUTH_CIPHER_NONE:
4784 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4785 break;
4786
4787 case WLAN_CIPHER_SUITE_WEP40:
4788 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4789 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4790 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
4791 else
4792 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4793 break;
4794
4795 case WLAN_CIPHER_SUITE_WEP104:
4796 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
4797 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
4798 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4799 else
4800 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4801 break;
4802
4803 case WLAN_CIPHER_SUITE_TKIP:
4804 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4805 break;
4806
4807 case WLAN_CIPHER_SUITE_CCMP:
4808 encryptionType = eCSR_ENCRYPT_TYPE_AES;
4809 break;
4810#ifdef FEATURE_WLAN_WAPI
4811 case WLAN_CIPHER_SUITE_SMS4:
4812 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
4813 break;
4814#endif
4815
4816#ifdef FEATURE_WLAN_CCX
4817 case WLAN_CIPHER_SUITE_KRK:
4818 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
4819 break;
4820#endif
4821 default:
4822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
4823 __func__, cipher);
4824 return -EOPNOTSUPP;
4825 }
4826 }
4827
4828 if (ucast)
4829 {
4830 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
4831 __func__, encryptionType);
4832 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4833 pWextState->roamProfile.EncryptionType.numEntries = 1;
4834 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4835 encryptionType;
4836 }
4837 else
4838 {
4839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
4840 __func__, encryptionType);
4841 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4842 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4843 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
4844 }
4845
4846 return 0;
4847}
4848
4849
4850/*
4851 * FUNCTION: wlan_hdd_cfg80211_set_ie
4852 * This function is used to parse WPA/RSN IE's.
4853 */
4854int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
4855 u8 *ie,
4856 size_t ie_len
4857 )
4858{
4859 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4860 u8 *genie = ie;
4861 v_U16_t remLen = ie_len;
4862#ifdef FEATURE_WLAN_WAPI
4863 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
4864 u16 *tmp;
4865 v_U16_t akmsuiteCount;
4866 int *akmlist;
4867#endif
4868 ENTER();
4869
4870 /* clear previous assocAddIE */
4871 pWextState->assocAddIE.length = 0;
4872 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
4873
4874 while (remLen >= 2)
4875 {
4876 v_U16_t eLen = 0;
4877 v_U8_t elementId;
4878 elementId = *genie++;
4879 eLen = *genie++;
4880 remLen -= 2;
4881
4882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
4883 __func__, elementId, eLen);
4884
4885 switch ( elementId )
4886 {
4887 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004888 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 -07004889 {
4890 hddLog(VOS_TRACE_LEVEL_ERROR,
4891 "%s: Invalid WPA IE", __func__);
4892 return -EINVAL;
4893 }
4894 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
4895 {
4896 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4897 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
4898 __func__, eLen + 2);
4899
4900 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4901 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004902 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
4903 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004904 VOS_ASSERT(0);
4905 return -ENOMEM;
4906 }
4907 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4908 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4909 pWextState->assocAddIE.length += eLen + 2;
4910
4911 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
4912 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4913 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4914 }
4915 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
4916 {
4917 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
4918 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
4919 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
4920 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
4921 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
4922 }
4923#ifdef WLAN_FEATURE_P2P
4924 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
4925 P2P_OUI_TYPE_SIZE))
4926 /*Consider P2P IE, only for P2P Client */
4927 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4928 {
4929 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4930 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
4931 __func__, eLen + 2);
4932
4933 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4934 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004935 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4936 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004937 VOS_ASSERT(0);
4938 return -ENOMEM;
4939 }
4940 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
4941 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4942 pWextState->assocAddIE.length += eLen + 2;
4943
4944 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4945 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4946 }
4947#endif
4948#ifdef WLAN_FEATURE_WFD
4949 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
4950 WFD_OUI_TYPE_SIZE))
4951 /*Consider WFD IE, only for P2P Client */
4952 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4953 {
4954 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4955 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
4956 __func__, eLen + 2);
4957
4958 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4959 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004960 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4961 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 VOS_ASSERT(0);
4963 return -ENOMEM;
4964 }
4965 // WFD IE is saved to Additional IE ; it should be accumulated to handle
4966 // WPS IE + P2P IE + WFD IE
4967 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4968 pWextState->assocAddIE.length += eLen + 2;
4969
4970 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4971 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4972 }
4973#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004974 /* Appending HS 2.0 Indication Element in Assiciation Request */
4975 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004976 HS20_OUI_TYPE_SIZE)) )
4977 {
4978 v_U16_t curAddIELen = pWextState->assocAddIE.length;
4979 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
4980 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004981
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004982 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
4983 {
Jeff Johnson902c9832012-12-10 14:28:09 -08004984 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
4985 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004986 VOS_ASSERT(0);
4987 return -ENOMEM;
4988 }
4989 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
4990 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004991
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004992 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
4993 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
4994 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07004995
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 break;
4997 case DOT11F_EID_RSN:
4998 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
4999 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5000 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5001 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5002 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5003 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005004 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5005 case DOT11F_EID_EXTCAP:
5006 {
5007 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5008 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5009 __func__, eLen + 2);
5010
5011 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5012 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005013 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5014 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005015 VOS_ASSERT(0);
5016 return -ENOMEM;
5017 }
5018 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5019 pWextState->assocAddIE.length += eLen + 2;
5020
5021 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5022 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5023 break;
5024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005025#ifdef FEATURE_WLAN_WAPI
5026 case WLAN_EID_WAPI:
5027 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5028 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5029 pAdapter->wapi_info.nWapiMode);
5030 tmp = (u16 *)ie;
5031 tmp = tmp + 2; // Skip element Id and Len, Version
5032 akmsuiteCount = WPA_GET_LE16(tmp);
5033 tmp = tmp + 1;
5034 akmlist = (int *)(tmp);
5035 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5036 {
5037 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5038 }
5039 else
5040 {
5041 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5042 VOS_ASSERT(0);
5043 return -EINVAL;
5044 }
5045
5046 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5047 {
5048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005049 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5051 }
5052 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5053 {
5054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005055 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5057 }
5058 break;
5059#endif
5060 default:
5061 hddLog (VOS_TRACE_LEVEL_ERROR,
5062 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005063 /* when Unknown IE is received we should break and continue
5064 * to the next IE in the buffer instead we were returning
5065 * so changing this to break */
5066 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005067 }
5068 genie += eLen;
5069 remLen -= eLen;
5070 }
5071 EXIT();
5072 return 0;
5073}
5074
5075/*
5076 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5077 * This function is used to initialize the security
5078 * parameters during connect operation.
5079 */
5080int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5081 struct cfg80211_connect_params *req
5082 )
5083{
5084 int status = 0;
5085 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5086 ENTER();
5087
5088 /*set wpa version*/
5089 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5090
5091 if (req->crypto.wpa_versions)
5092 {
5093 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5094 && ( (req->ie_len)
5095 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5096 // Make sure that it is including a WPA IE.
5097 /* Currently NL is putting WPA version 1 even for open,
5098 * since p2p ie is also put in same buffer.
5099 * */
5100 {
5101 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5102 }
5103 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5104 {
5105 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5106 }
5107 }
5108
5109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5110 pWextState->wpaVersion);
5111
5112 /*set authentication type*/
5113 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5114
5115 if (0 > status)
5116 {
5117 hddLog(VOS_TRACE_LEVEL_ERROR,
5118 "%s: failed to set authentication type ", __func__);
5119 return status;
5120 }
5121
5122 /*set key mgmt type*/
5123 if (req->crypto.n_akm_suites)
5124 {
5125 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5126 if (0 > status)
5127 {
5128 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5129 __func__);
5130 return status;
5131 }
5132 }
5133
5134 /*set pairwise cipher type*/
5135 if (req->crypto.n_ciphers_pairwise)
5136 {
5137 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5138 req->crypto.ciphers_pairwise[0], true);
5139 if (0 > status)
5140 {
5141 hddLog(VOS_TRACE_LEVEL_ERROR,
5142 "%s: failed to set unicast cipher type", __func__);
5143 return status;
5144 }
5145 }
5146 else
5147 {
5148 /*Reset previous cipher suite to none*/
5149 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5150 if (0 > status)
5151 {
5152 hddLog(VOS_TRACE_LEVEL_ERROR,
5153 "%s: failed to set unicast cipher type", __func__);
5154 return status;
5155 }
5156 }
5157
5158 /*set group cipher type*/
5159 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5160 false);
5161
5162 if (0 > status)
5163 {
5164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5165 __func__);
5166 return status;
5167 }
5168
5169 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5170 if (req->ie_len)
5171 {
5172 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5173 if ( 0 > status)
5174 {
5175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5176 __func__);
5177 return status;
5178 }
5179 }
5180
5181 /*incase of WEP set default key information*/
5182 if (req->key && req->key_len)
5183 {
5184 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5185 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5186 )
5187 {
5188 if ( IW_AUTH_KEY_MGMT_802_1X
5189 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5190 {
5191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5192 __func__);
5193 return -EOPNOTSUPP;
5194 }
5195 else
5196 {
5197 u8 key_len = req->key_len;
5198 u8 key_idx = req->key_idx;
5199
5200 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5201 && (CSR_MAX_NUM_KEY > key_idx)
5202 )
5203 {
5204 hddLog(VOS_TRACE_LEVEL_INFO,
5205 "%s: setting default wep key, key_idx = %hu key_len %hu",
5206 __func__, key_idx, key_len);
5207 vos_mem_copy(
5208 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5209 req->key, key_len);
5210 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5211 (u8)key_len;
5212 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5213 }
5214 }
5215 }
5216 }
5217
5218 return status;
5219}
5220
5221/*
5222 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5223 * This function is used to initialize the security
5224 * parameters during connect operation.
5225 */
5226static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5227 struct net_device *ndev,
5228 struct cfg80211_connect_params *req
5229 )
5230{
5231 int status = 0;
5232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5233 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5234 hdd_context_t *pHddCtx = NULL;
5235
5236 ENTER();
5237
5238 hddLog(VOS_TRACE_LEVEL_INFO,
5239 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5240
5241 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5242 {
5243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5244 "%s:LOGP in Progress. Ignore!!!", __func__);
5245 return -EAGAIN;
5246 }
5247
5248#ifdef WLAN_BTAMP_FEATURE
5249 //Infra connect not supported when AMP traffic is on.
5250 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5251 {
5252 hddLog(VOS_TRACE_LEVEL_ERROR,
5253 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005254 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005255 }
5256#endif
5257 /*initialise security parameters*/
5258 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5259
5260 if ( 0 > status)
5261 {
5262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5263 __func__);
5264 return status;
5265 }
5266
5267 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005268 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005269 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5270 (vos_concurrent_sessions_running()))
5271 {
5272 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5273
5274 if (NULL != pVosContext)
5275 {
5276 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5277 if(NULL != pHddCtx)
5278 {
5279 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5280 }
5281 }
5282 }
5283
Mohit Khanna765234a2012-09-11 15:08:35 -07005284 if ( req->channel )
5285 {
5286 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5287 req->ssid_len, req->bssid,
5288 req->channel->hw_value);
5289 }
5290 else
5291 {
5292 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5293 req->ssid_len, req->bssid,
5294 0);
5295 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005296
5297 if (0 > status)
5298 {
5299 //ReEnable BMPS if disabled
5300 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5301 (NULL != pHddCtx))
5302 {
5303 //ReEnable Bmps and Imps back
5304 hdd_enable_bmps_imps(pHddCtx);
5305 }
5306
5307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5308 return status;
5309 }
5310 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5311 EXIT();
5312 return status;
5313}
5314
5315
5316/*
5317 * FUNCTION: wlan_hdd_cfg80211_disconnect
5318 * This function is used to issue a disconnect request to SME
5319 */
5320static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5321 struct net_device *dev,
5322 u16 reason
5323 )
5324{
5325 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5326 tCsrRoamProfile *pRoamProfile =
5327 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5328 int status = 0;
5329 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005330#ifdef FEATURE_WLAN_TDLS
5331 tANI_U8 staIdx;
5332#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005333
5334 ENTER();
5335
5336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5337 __func__,pAdapter->device_mode);
5338
5339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5340 __func__, reason);
5341
5342 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5343 {
5344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5345 "%s:LOGP in Progress. Ignore!!!",__func__);
5346 return -EAGAIN;
5347 }
5348 if (NULL != pRoamProfile)
5349 {
5350 /*issue disconnect request to SME, if station is in connected state*/
5351 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5352 {
5353 eCsrRoamDisconnectReason reasonCode =
5354 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5355 switch(reason)
5356 {
5357 case WLAN_REASON_MIC_FAILURE:
5358 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5359 break;
5360
5361 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5362 case WLAN_REASON_DISASSOC_AP_BUSY:
5363 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5364 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5365 break;
5366
5367 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5368 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5369 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5370 break;
5371
5372 case WLAN_REASON_DEAUTH_LEAVING:
5373 default:
5374 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5375 break;
5376 }
5377 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5378 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5379 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5380
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005381#ifdef FEATURE_WLAN_TDLS
5382 /* First clean up the tdls peers if any */
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005383 for (staIdx = 1 ; staIdx <= HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005384 {
5385 if (pHddStaCtx->conn_info.staId[staIdx])
5386 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005387 uint8 *mac;
5388 mac = pHddStaCtx->conn_info.peerMacAddress[staIdx].bytes;
5389 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
5390 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d %02x:%02x:%02x:%02x:%02x:%02x",
5391 __func__, pHddStaCtx->conn_info.staId[staIdx], pAdapter->sessionId,
5392 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005393 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
5394 pAdapter->sessionId,
5395 pHddStaCtx->conn_info.peerMacAddress[staIdx].bytes);
5396 }
5397 }
5398#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 /*issue disconnect*/
5400 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5401 pAdapter->sessionId, reasonCode);
5402
5403 if ( 0 != status)
5404 {
5405 hddLog(VOS_TRACE_LEVEL_ERROR,
5406 "%s csrRoamDisconnect failure, returned %d \n",
5407 __func__, (int)status );
5408 return -EINVAL;
5409 }
5410
5411 wait_for_completion_interruptible_timeout(
5412 &pAdapter->disconnect_comp_var,
5413 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5414
5415
5416 /*stop tx queues*/
5417 netif_tx_disable(dev);
5418 netif_carrier_off(dev);
5419 }
5420 }
5421 else
5422 {
5423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5424 }
5425
5426 return status;
5427}
5428
5429/*
5430 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5431 * This function is used to initialize the security
5432 * settings in IBSS mode.
5433 */
5434static int wlan_hdd_cfg80211_set_privacy_ibss(
5435 hdd_adapter_t *pAdapter,
5436 struct cfg80211_ibss_params *params
5437 )
5438{
5439 int status = 0;
5440 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5441 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5442 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5443
5444 ENTER();
5445
5446 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5447
5448 if (params->ie_len && ( NULL != params->ie) )
5449 {
5450 if (WLAN_EID_RSN == params->ie[0])
5451 {
5452 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5453 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5454 }
5455 else
5456 {
5457 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5458 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5459 }
5460 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5461
5462 if (0 > status)
5463 {
5464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5465 __func__);
5466 return status;
5467 }
5468 }
5469
5470 pWextState->roamProfile.AuthType.authType[0] =
5471 pHddStaCtx->conn_info.authType =
5472 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5473
5474 if (params->privacy)
5475 {
5476 /* Security enabled IBSS, At this time there is no information available
5477 * about the security paramters, so initialise the encryption type to
5478 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5479 * The correct security parameters will be updated later in
5480 * wlan_hdd_cfg80211_add_key */
5481 /* Hal expects encryption type to be set inorder
5482 *enable privacy bit in beacons */
5483
5484 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5485 }
5486
5487 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5488 pWextState->roamProfile.EncryptionType.numEntries = 1;
5489 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5490
5491 return status;
5492}
5493
5494/*
5495 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5496 * This function is used to create/join an IBSS
5497 */
5498static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5499 struct net_device *dev,
5500 struct cfg80211_ibss_params *params
5501 )
5502{
5503 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5504 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5505 tCsrRoamProfile *pRoamProfile;
5506 int status;
5507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5508
5509 ENTER();
5510
5511 hddLog(VOS_TRACE_LEVEL_INFO,
5512 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5513
5514 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5515 {
5516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5517 "%s:LOGP in Progress. Ignore!!!", __func__);
5518 return -EAGAIN;
5519 }
5520
5521 if (NULL == pWextState)
5522 {
5523 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5524 __func__);
5525 return -EIO;
5526 }
5527
5528 pRoamProfile = &pWextState->roamProfile;
5529
5530 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5531 {
5532 hddLog (VOS_TRACE_LEVEL_ERROR,
5533 "%s Interface type is not set to IBSS \n", __func__);
5534 return -EINVAL;
5535 }
5536
5537 /* Set Channel */
5538 if (NULL != params->channel)
5539 {
5540 u8 channelNum;
5541 if (IEEE80211_BAND_5GHZ == params->channel->band)
5542 {
5543 hddLog(VOS_TRACE_LEVEL_ERROR,
5544 "%s: IBSS join is called with unsupported band %d",
5545 __func__, params->channel->band);
5546 return -EOPNOTSUPP;
5547 }
5548
5549 /* Get channel number */
5550 channelNum =
5551 ieee80211_frequency_to_channel(params->channel->center_freq);
5552
5553 /*TODO: use macro*/
5554 if (14 >= channelNum)
5555 {
5556 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5557 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5558 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5559 int indx;
5560
5561 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5562 validChan, &numChans))
5563 {
5564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5565 __func__);
5566 return -EOPNOTSUPP;
5567 }
5568
5569 for (indx = 0; indx < numChans; indx++)
5570 {
5571 if (channelNum == validChan[indx])
5572 {
5573 break;
5574 }
5575 }
5576 if (indx >= numChans)
5577 {
5578 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5579 __func__, channelNum);
5580 return -EINVAL;
5581 }
5582 /* Set the Operational Channel */
5583 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5584 channelNum);
5585 pRoamProfile->ChannelInfo.numOfChannels = 1;
5586 pHddStaCtx->conn_info.operationChannel = channelNum;
5587 pRoamProfile->ChannelInfo.ChannelList =
5588 &pHddStaCtx->conn_info.operationChannel;
5589 }
5590 else
5591 {
5592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5593 __func__, channelNum);
5594 return -EINVAL;
5595 }
5596 }
5597
5598 /* Initialize security parameters */
5599 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5600 if (status < 0)
5601 {
5602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5603 __func__);
5604 return status;
5605 }
5606
5607 /* Issue connect start */
5608 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005609 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005610
5611 if (0 > status)
5612 {
5613 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5614 return status;
5615 }
5616
5617 return 0;
5618}
5619
5620/*
5621 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5622 * This function is used to leave an IBSS
5623 */
5624static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5625 struct net_device *dev
5626 )
5627{
5628 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5629 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5630 tCsrRoamProfile *pRoamProfile;
5631
5632 ENTER();
5633
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005634 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5635 {
5636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5637 "%s:LOGP in Progress. Ignore!!!", __func__);
5638 return -EAGAIN;
5639 }
5640
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5642 if (NULL == pWextState)
5643 {
5644 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5645 __func__);
5646 return -EIO;
5647 }
5648
5649 pRoamProfile = &pWextState->roamProfile;
5650
5651 /* Issue disconnect only if interface type is set to IBSS */
5652 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5653 {
5654 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5655 __func__);
5656 return -EINVAL;
5657 }
5658
5659 /* Issue Disconnect request */
5660 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5661 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5662 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5663
5664 return 0;
5665}
5666
5667/*
5668 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5669 * This function is used to set the phy parameters
5670 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5671 */
5672static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5673 u32 changed)
5674{
5675 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5676 tHalHandle hHal = pHddCtx->hHal;
5677
5678 ENTER();
5679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005680 if ( pHddCtx->isLogpInProgress )
5681 {
5682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5683 "%s:LOGP in Progress. Ignore!!!", __func__);
5684 return -EAGAIN;
5685 }
5686
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5688 {
5689 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5690 WNI_CFG_RTS_THRESHOLD_STAMAX :
5691 wiphy->rts_threshold;
5692
5693 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5694 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5695 {
5696 hddLog(VOS_TRACE_LEVEL_ERROR,
5697 "%s: Invalid RTS Threshold value %hu",
5698 __func__, rts_threshold);
5699 return -EINVAL;
5700 }
5701
5702 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5703 rts_threshold, ccmCfgSetCallback,
5704 eANI_BOOLEAN_TRUE))
5705 {
5706 hddLog(VOS_TRACE_LEVEL_ERROR,
5707 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5708 __func__, rts_threshold);
5709 return -EIO;
5710 }
5711
5712 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
5713 rts_threshold);
5714 }
5715
5716 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5717 {
5718 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5719 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5720 wiphy->frag_threshold;
5721
5722 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
5723 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
5724 {
5725 hddLog(VOS_TRACE_LEVEL_ERROR,
5726 "%s: Invalid frag_threshold value %hu", __func__,
5727 frag_threshold);
5728 return -EINVAL;
5729 }
5730
5731 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5732 frag_threshold, ccmCfgSetCallback,
5733 eANI_BOOLEAN_TRUE))
5734 {
5735 hddLog(VOS_TRACE_LEVEL_ERROR,
5736 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
5737 __func__, frag_threshold);
5738 return -EIO;
5739 }
5740
5741 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5742 frag_threshold);
5743 }
5744
5745 if ((changed & WIPHY_PARAM_RETRY_SHORT)
5746 || (changed & WIPHY_PARAM_RETRY_LONG))
5747 {
5748 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
5749 wiphy->retry_short :
5750 wiphy->retry_long;
5751
5752 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
5753 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
5754 {
5755 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
5756 __func__, retry_value);
5757 return -EINVAL;
5758 }
5759
5760 if (changed & WIPHY_PARAM_RETRY_SHORT)
5761 {
5762 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
5763 retry_value, ccmCfgSetCallback,
5764 eANI_BOOLEAN_TRUE))
5765 {
5766 hddLog(VOS_TRACE_LEVEL_ERROR,
5767 "%s: ccmCfgSetInt failed for long retry count %hu",
5768 __func__, retry_value);
5769 return -EIO;
5770 }
5771 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
5772 __func__, retry_value);
5773 }
5774 else if (changed & WIPHY_PARAM_RETRY_SHORT)
5775 {
5776 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
5777 retry_value, ccmCfgSetCallback,
5778 eANI_BOOLEAN_TRUE))
5779 {
5780 hddLog(VOS_TRACE_LEVEL_ERROR,
5781 "%s: ccmCfgSetInt failed for short retry count %hu",
5782 __func__, retry_value);
5783 return -EIO;
5784 }
5785 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
5786 __func__, retry_value);
5787 }
5788 }
5789
5790 return 0;
5791}
5792
5793/*
5794 * FUNCTION: wlan_hdd_cfg80211_set_txpower
5795 * This function is used to set the txpower
5796 */
5797static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
5798#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
5799 enum tx_power_setting type,
5800#else
5801 enum nl80211_tx_power_setting type,
5802#endif
5803 int dbm)
5804{
5805 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5806 tHalHandle hHal = pHddCtx->hHal;
5807 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5808 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5809
5810 ENTER();
5811
5812 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
5813 dbm, ccmCfgSetCallback,
5814 eANI_BOOLEAN_TRUE))
5815 {
5816 hddLog(VOS_TRACE_LEVEL_ERROR,
5817 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
5818 return -EIO;
5819 }
5820
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005821 if ( pHddCtx->isLogpInProgress )
5822 {
5823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5824 "%s:LOGP in Progress. Ignore!!!", __func__);
5825 return -EAGAIN;
5826 }
5827
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
5829 dbm);
5830
5831 switch(type)
5832 {
5833 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
5834 /* Fall through */
5835 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
5836 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
5837 {
5838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
5839 __func__);
5840 return -EIO;
5841 }
5842 break;
5843 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
5844 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
5845 __func__);
5846 return -EOPNOTSUPP;
5847 break;
5848 default:
5849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
5850 __func__, type);
5851 return -EIO;
5852 }
5853
5854 return 0;
5855}
5856
5857/*
5858 * FUNCTION: wlan_hdd_cfg80211_get_txpower
5859 * This function is used to read the txpower
5860 */
5861static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
5862{
5863
5864 hdd_adapter_t *pAdapter;
5865 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5866
Jeff Johnsone7245742012-09-05 17:12:55 -07005867 ENTER();
5868
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 if (NULL == pHddCtx)
5870 {
5871 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
5872 *dbm = 0;
5873 return -ENOENT;
5874 }
5875
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005876 if ( pHddCtx->isLogpInProgress )
5877 {
5878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5879 "%s:LOGP in Progress. Ignore!!!", __func__);
5880 return -EAGAIN;
5881 }
5882
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5884 if (NULL == pAdapter)
5885 {
5886 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
5887 return -ENOENT;
5888 }
5889
5890 wlan_hdd_get_classAstats(pAdapter);
5891 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
5892
Jeff Johnsone7245742012-09-05 17:12:55 -07005893 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 return 0;
5895}
5896
5897static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
5898 u8* mac, struct station_info *sinfo)
5899{
5900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5901 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5902 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
5903 tANI_U8 rate_flags;
5904
5905 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
5906 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07005907
5908 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
5909 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
5910 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
5911 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
5912 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
5913 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
5914 tANI_U16 maxRate = 0;
5915 tANI_U16 myRate;
5916 tANI_U16 currentRate = 0;
5917 tANI_U8 maxSpeedMCS = 0;
5918 tANI_U8 maxMCSIdx = 0;
5919 tANI_U8 rateFlag = 1;
5920 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005921 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07005922
Jeff Johnsone7245742012-09-05 17:12:55 -07005923 ENTER();
5924
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
5926 (0 == ssidlen))
5927 {
5928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
5929 " Invalid ssidlen, %d", __func__, ssidlen);
5930 /*To keep GUI happy*/
5931 return 0;
5932 }
5933
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005934 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5935 {
5936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5937 "%s:LOGP in Progress. Ignore!!!", __func__);
5938 return -EAGAIN;
5939 }
5940
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
5942 sinfo->filled |= STATION_INFO_SIGNAL;
5943
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07005944 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
5946
5947 //convert to the UI units of 100kbps
5948 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
5949
5950#ifdef LINKSPEED_DEBUG_ENABLED
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005951 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 -07005952 sinfo->signal,
5953 pCfg->reportMaxLinkSpeed,
5954 myRate,
5955 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005956 (int) pCfg->linkSpeedRssiMid,
5957 (int) pCfg->linkSpeedRssiLow,
5958 (int) rate_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005959#endif //LINKSPEED_DEBUG_ENABLED
5960
5961 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
5962 {
5963 // we do not want to necessarily report the current speed
5964 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
5965 {
5966 // report the max possible speed
5967 rssidx = 0;
5968 }
5969 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
5970 {
5971 // report the max possible speed with RSSI scaling
5972 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
5973 {
5974 // report the max possible speed
5975 rssidx = 0;
5976 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005977 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 {
5979 // report middle speed
5980 rssidx = 1;
5981 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005982 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
5983 {
5984 // report middle speed
5985 rssidx = 2;
5986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 else
5988 {
5989 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07005990 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 }
5992 }
5993 else
5994 {
5995 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
5996 hddLog(VOS_TRACE_LEVEL_ERROR,
5997 "%s: Invalid value for reportMaxLinkSpeed: %u",
5998 __func__, pCfg->reportMaxLinkSpeed);
5999 rssidx = 0;
6000 }
6001
6002 maxRate = 0;
6003
6004 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306005 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6006 OperationalRates, &ORLeng))
6007 {
6008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6009 /*To keep GUI happy*/
6010 return 0;
6011 }
6012
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 for (i = 0; i < ORLeng; i++)
6014 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006015 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 {
6017 /* Validate Rate Set */
6018 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6019 {
6020 currentRate = supported_data_rate[j].supported_rate[rssidx];
6021 break;
6022 }
6023 }
6024 /* Update MAX rate */
6025 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6026 }
6027
6028 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306029 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6030 ExtendedRates, &ERLeng))
6031 {
6032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6033 /*To keep GUI happy*/
6034 return 0;
6035 }
6036
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 for (i = 0; i < ERLeng; i++)
6038 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006039 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 {
6041 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6042 {
6043 currentRate = supported_data_rate[j].supported_rate[rssidx];
6044 break;
6045 }
6046 }
6047 /* Update MAX rate */
6048 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6049 }
6050
6051 /* Get MCS Rate Set -- but only if we are connected at MCS
6052 rates or if we are always reporting max speed or if we have
6053 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006054 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306056 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6057 MCSRates, &MCSLeng))
6058 {
6059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6060 /*To keep GUI happy*/
6061 return 0;
6062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 rateFlag = 0;
6064 if (rate_flags & eHAL_TX_RATE_HT40)
6065 {
6066 rateFlag |= 1;
6067 }
6068 if (rate_flags & eHAL_TX_RATE_SGI)
6069 {
6070 rateFlag |= 2;
6071 }
6072
6073 for (i = 0; i < MCSLeng; i++)
6074 {
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006075 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6076 for (j = 0; j < temp; j++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 {
6078 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6079 {
6080 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6081 break;
6082 }
6083 }
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006084 if ((j < temp) && (currentRate > maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 {
6086 maxRate = currentRate;
6087 maxSpeedMCS = 1;
6088 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6089 }
6090 }
6091 }
6092
6093 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006094 if (((maxRate < myRate) && (0 == rssidx)) ||
6095 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006096 {
6097 maxRate = myRate;
6098 if (rate_flags & eHAL_TX_RATE_LEGACY)
6099 {
6100 maxSpeedMCS = 0;
6101 }
6102 else
6103 {
6104 maxSpeedMCS = 1;
6105 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6106 }
6107 }
6108
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006109 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006110 {
6111 sinfo->txrate.legacy = maxRate;
6112#ifdef LINKSPEED_DEBUG_ENABLED
6113 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6114#endif //LINKSPEED_DEBUG_ENABLED
6115 }
6116 else
6117 {
6118 sinfo->txrate.mcs = maxMCSIdx;
6119 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6120 if (rate_flags & eHAL_TX_RATE_SGI)
6121 {
6122 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6123 }
6124 if (rate_flags & eHAL_TX_RATE_HT40)
6125 {
6126 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6127 }
6128#ifdef LINKSPEED_DEBUG_ENABLED
6129 pr_info("Reporting MCS rate %d flags %x\n",
6130 sinfo->txrate.mcs,
6131 sinfo->txrate.flags );
6132#endif //LINKSPEED_DEBUG_ENABLED
6133 }
6134 }
6135 else
6136 {
6137 // report current rate instead of max rate
6138
6139 if (rate_flags & eHAL_TX_RATE_LEGACY)
6140 {
6141 //provide to the UI in units of 100kbps
6142 sinfo->txrate.legacy = myRate;
6143#ifdef LINKSPEED_DEBUG_ENABLED
6144 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6145#endif //LINKSPEED_DEBUG_ENABLED
6146 }
6147 else
6148 {
6149 //must be MCS
6150 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6151 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6152 if (rate_flags & eHAL_TX_RATE_SGI)
6153 {
6154 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6155 }
6156 if (rate_flags & eHAL_TX_RATE_HT40)
6157 {
6158 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6159 }
6160#ifdef LINKSPEED_DEBUG_ENABLED
6161 pr_info("Reporting actual MCS rate %d flags %x\n",
6162 sinfo->txrate.mcs,
6163 sinfo->txrate.flags );
6164#endif //LINKSPEED_DEBUG_ENABLED
6165 }
6166 }
6167 sinfo->filled |= STATION_INFO_TX_BITRATE;
6168
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006169 sinfo->tx_packets =
6170 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6171 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6172 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6173 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6174
6175 sinfo->tx_retries =
6176 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6177 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6178 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6179 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6180
6181 sinfo->tx_failed =
6182 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6183 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6184 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6185 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6186
6187 sinfo->filled |=
6188 STATION_INFO_TX_PACKETS |
6189 STATION_INFO_TX_RETRIES |
6190 STATION_INFO_TX_FAILED;
6191
6192 EXIT();
6193 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006194}
6195
6196static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6197 struct net_device *dev, bool mode, v_SINT_t timeout)
6198{
6199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6200 VOS_STATUS vos_status;
6201
Jeff Johnsone7245742012-09-05 17:12:55 -07006202 ENTER();
6203
Jeff Johnson295189b2012-06-20 16:38:30 -07006204 if (NULL == pAdapter)
6205 {
6206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6207 return -ENODEV;
6208 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006209 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6210 {
6211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6212 "%s:LOGP in Progress. Ignore!!!", __func__);
6213 return -EAGAIN;
6214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006215
6216 /**The get power cmd from the supplicant gets updated by the nl only
6217 *on successful execution of the function call
6218 *we are oppositely mapped w.r.t mode in the driver
6219 **/
6220 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6221
Jeff Johnsone7245742012-09-05 17:12:55 -07006222 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 if (VOS_STATUS_E_FAILURE == vos_status)
6224 {
6225 return -EINVAL;
6226 }
6227 return 0;
6228}
6229
6230
6231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6232static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6233 struct net_device *netdev,
6234 u8 key_index)
6235{
Jeff Johnsone7245742012-09-05 17:12:55 -07006236 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 return 0;
6238}
6239#endif //LINUX_VERSION_CODE
6240
6241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6242static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6243 struct net_device *dev,
6244 struct ieee80211_txq_params *params)
6245{
Jeff Johnsone7245742012-09-05 17:12:55 -07006246 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 return 0;
6248}
6249#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6250static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6251 struct ieee80211_txq_params *params)
6252{
Jeff Johnsone7245742012-09-05 17:12:55 -07006253 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 return 0;
6255}
6256#endif //LINUX_VERSION_CODE
6257
6258static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6259 struct net_device *dev, u8 *mac)
6260{
6261 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006262 VOS_STATUS vos_status;
6263 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006264
Jeff Johnsone7245742012-09-05 17:12:55 -07006265 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6267 {
6268 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6269 return -EINVAL;
6270 }
6271
6272 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6273 {
6274 hddLog( LOGE,
6275 "%s: Wlan Load/Unload is in progress", __func__);
6276 return -EBUSY;
6277 }
6278
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006279 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6280 {
6281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6282 "%s:LOGP in Progress. Ignore!!!", __func__);
6283 return -EAGAIN;
6284 }
6285
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
6287#ifdef WLAN_FEATURE_P2P
6288 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6289#endif
6290 )
6291 {
6292 if( NULL == mac )
6293 {
6294 v_U16_t i;
6295 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6296 {
6297 if(pAdapter->aStaInfo[i].isUsed)
6298 {
6299 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6300 hddLog(VOS_TRACE_LEVEL_INFO,
6301 "%s: Delete STA with MAC::"
6302 "%02x:%02x:%02x:%02x:%02x:%02x",
6303 __func__,
6304 macAddr[0], macAddr[1], macAddr[2],
6305 macAddr[3], macAddr[4], macAddr[5]);
6306 hdd_softap_sta_deauth(pAdapter, macAddr);
6307 }
6308 }
6309 }
6310 else
6311 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006312
6313 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6314 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6315 {
6316 hddLog(VOS_TRACE_LEVEL_INFO,
6317 "%s: Skip this DEL STA as this is not used::"
6318 "%02x:%02x:%02x:%02x:%02x:%02x",
6319 __func__,
6320 mac[0], mac[1], mac[2],
6321 mac[3], mac[4], mac[5]);
6322 return -ENOENT;
6323 }
6324
6325 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6326 {
6327 hddLog(VOS_TRACE_LEVEL_INFO,
6328 "%s: Skip this DEL STA as deauth is in progress::"
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
6336 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6337
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 hddLog(VOS_TRACE_LEVEL_INFO,
6339 "%s: Delete STA with MAC::"
6340 "%02x:%02x:%02x:%02x:%02x:%02x",
6341 __func__,
6342 mac[0], mac[1], mac[2],
6343 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006344
6345 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6346 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6347 {
6348 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6349 hddLog(VOS_TRACE_LEVEL_INFO,
6350 "%s: STA removal failed for ::"
6351 "%02x:%02x:%02x:%02x:%02x:%02x",
6352 __func__,
6353 mac[0], mac[1], mac[2],
6354 mac[3], mac[4], mac[5]);
6355 return -ENOENT;
6356 }
6357
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 }
6359 }
6360
6361 EXIT();
6362
6363 return 0;
6364}
6365
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006366#ifdef FEATURE_WLAN_TDLS
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006367static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6368 struct net_device *dev, u8 *mac)
6369{
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006370 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006372 VOS_STATUS status;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006373
Jeff Johnsone7245742012-09-05 17:12:55 -07006374 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006375
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006376 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006377 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006379 "Invalid arguments");
6380 return -EINVAL;
6381 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006382 if (pHddCtx->isLogpInProgress)
6383 {
6384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6385 "%s:LOGP in Progress. Ignore!!!", __func__);
6386 return -EBUSY;
6387 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006388
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006389 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006390 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006391 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006393 "TDLS Disabled in INI OR not enabled in FW.\
6394 Cannot process TDLS commands \n");
6395 return -ENOTSUPP;
6396 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006397
6398 if (wlan_hdd_tdls_is_progress(mac, TRUE))
6399 {
6400 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6401 "%s: TDLS setup is ongoing. Request declined.",__func__);
6402 return -EPERM;
6403 }
6404
Lee Hoonkic1262f22013-01-24 21:59:00 -08006405 /* first to check if we reached to maximum supported TDLS peer.
6406 TODO: for now, return -EPERM looks working fine,
6407 but need to check if any other errno fit into this category.*/
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006408 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers())
Lee Hoonkic1262f22013-01-24 21:59:00 -08006409 {
6410 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6411 "%s: TDLS Max peer already connected. Request declined. \n",
6412 __func__);
6413 return -EPERM;
6414 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006415 else
6416 {
6417 hddTdlsPeer_t *pTdlsPeer;
6418 pTdlsPeer = wlan_hdd_tdls_find_peer(mac);
6419 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
6420 {
6421 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6422 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
6423 __func__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
6424 return -EPERM;
6425 }
6426 }
6427
6428 wlan_hdd_tdls_set_connection_progress(mac,TRUE);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006429
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006430 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6431
6432 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6433 pAdapter->sessionId, mac);
6434
6435 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
6436 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6437
6438 if (!status)
6439 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006440 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006441 "%s: timeout waiting for tdls add station indication",
6442 __func__);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006443 wlan_hdd_tdls_set_connection_progress(mac, FALSE);
6444 return -EPERM;
6445 }
6446 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6447 {
6448 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6449 "%s: Add Station is unsucessful", __func__);
6450 wlan_hdd_tdls_set_connection_progress(mac, FALSE);
6451 return -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006452 }
6453
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006454 return 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006455}
6456#endif
6457
6458static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6459 struct net_device *dev, u8 *mac, struct station_parameters *params)
6460{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006461 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006462#ifdef FEATURE_WLAN_TDLS
6463 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006464 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006465 mask = params->sta_flags_mask;
6466
6467 set = params->sta_flags_set;
6468
Lee Hoonkic1262f22013-01-24 21:59:00 -08006469 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6470 "%s: mask 0x%x set 0x%x\n",__func__, mask, set);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006471
6472 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6473 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006474 status = wlan_hdd_tdls_add_station(wiphy, dev, mac);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006475 }
6476 }
6477#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006478 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006479}
6480
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006481
6482#ifdef FEATURE_WLAN_LFR
6483static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006484 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006485{
6486#define MAX_PMKSAIDS_IN_CACHE 8
6487 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006488 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006489 tANI_U32 j=0;
6490 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6491 tHalHandle halHandle;
6492 eHalStatus result;
6493 tANI_U8 BSSIDMatched = 0;
6494
Jeff Johnsone7245742012-09-05 17:12:55 -07006495 ENTER();
6496
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006497 // Validate pAdapter
6498 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6499 {
6500 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6501 return -EINVAL;
6502 }
6503
6504 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6505 {
6506 hddLog( LOGE,
6507 "%s: Wlan Load/Unload is in progress", __func__);
6508 return -EBUSY;
6509 }
6510
6511 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6512 {
6513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6514 "%s:LOGP in Progress. Ignore!!!", __func__);
6515 return -EAGAIN;
6516 }
6517
6518 // Retrieve halHandle
6519 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6520
6521 for (j = 0; j < i; j++)
6522 {
6523 if(vos_mem_compare(PMKIDCache[j].BSSID,
6524 pmksa->bssid, WNI_CFG_BSSID_LEN))
6525 {
6526 /* BSSID matched previous entry. Overwrite it. */
6527 BSSIDMatched = 1;
6528 vos_mem_copy(PMKIDCache[j].BSSID,
6529 pmksa->bssid, WNI_CFG_BSSID_LEN);
6530 vos_mem_copy(PMKIDCache[j].PMKID,
6531 pmksa->pmkid,
6532 CSR_RSN_PMKID_SIZE);
6533 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006534 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006535 dump_bssid(pmksa->bssid);
6536 dump_pmkid(halHandle, pmksa->pmkid);
6537 break;
6538 }
6539 }
6540
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006541 /* Check we compared all entries,if then take the first slot now */
6542 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6543
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006544 if (!BSSIDMatched)
6545 {
6546 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6547 vos_mem_copy(PMKIDCache[i].BSSID,
6548 pmksa->bssid, ETHER_ADDR_LEN);
6549 vos_mem_copy(PMKIDCache[i].PMKID,
6550 pmksa->pmkid,
6551 CSR_RSN_PMKID_SIZE);
6552 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006553 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006554 dump_bssid(pmksa->bssid);
6555 dump_pmkid(halHandle, pmksa->pmkid);
6556 // Increment the HDD Local Cache index
6557 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6558 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6559 }
6560
6561
6562 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6563 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006564 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006565 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006566 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006567 // Finally set the PMKSA ID Cache in CSR
6568 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6569 PMKIDCache,
6570 i );
6571 return 0;
6572}
6573
6574
6575static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006576 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006577{
Jeff Johnsone7245742012-09-05 17:12:55 -07006578 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006579 // TODO: Implement this later.
6580 return 0;
6581}
6582
6583static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6584{
Jeff Johnsone7245742012-09-05 17:12:55 -07006585 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006586 // TODO: Implement this later.
6587 return 0;
6588}
6589#endif
6590
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006591#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6592static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6593 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6594{
6595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6596 hdd_station_ctx_t *pHddStaCtx;
6597
6598 if (NULL == pAdapter)
6599 {
6600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6601 return -ENODEV;
6602 }
6603
6604 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6605
6606 // Added for debug on reception of Re-assoc Req.
6607 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6608 {
6609 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6610 ftie->ie_len);
6611 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6612 }
6613
6614#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6615 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6616 ftie->ie_len);
6617#endif
6618
6619 // Pass the received FT IEs to SME
6620 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, ftie->ie,
6621 ftie->ie_len);
6622 return 0;
6623}
6624#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006625
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006626#ifdef FEATURE_WLAN_TDLS
6627static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6628 u8 *peer, u8 action_code, u8 dialog_token,
6629 u16 status_code, const u8 *buf, size_t len)
6630{
6631
6632 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6633 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006634 u8 peerMac[6];
6635 VOS_STATUS status;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006636 int ret = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006637 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006638
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006639 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006640 {
6641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6642 "Invalid arguments");
6643 return -EINVAL;
6644 }
6645
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006646 if (pHddCtx->isLogpInProgress)
6647 {
6648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6649 "%s:LOGP in Progress. Ignore!!!", __func__);
6650 return -EBUSY;
6651 }
6652
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006653 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006654 FALSE == sme_IsFeatureSupportedByFW(TDLS))
6655 {
6656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6657 "TDLS Disabled in INI OR not enabled in FW.\
6658 Cannot process TDLS commands \n");
6659 return -ENOTSUPP;
6660 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006661
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006662 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
6663 {
6664 if (wlan_hdd_tdls_is_progress(peer, TRUE))
6665 {
6666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6667 "%s: TDLS setup is ongoing. Request declined.", __func__);
6668 return -EPERM;
6669 }
6670 }
6671
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006672 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
6673 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08006674 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006675 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers())
Lee Hoonkic1262f22013-01-24 21:59:00 -08006676 {
6677 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6678 we return error code at 'add_station()'. Hence we have this
6679 check again in addtion to add_station().
6680 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006681 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006682 {
6683 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6684 "%s: TDLS Max peer already connected. Request declined. \n",
6685 __func__);
6686 return -EPERM;
6687 }
6688 else
6689 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006690 /* maximum reached. tweak to send error code to peer and return
6691 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006692 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
6693 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6694 "%s: TDLS Max peer already connected send response status %d \n",
6695 __func__,status_code);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006696 ret = -EPERM;
6697 /* fall through to send setup resp with failure status
6698 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006699 }
6700 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006701 else
6702 {
6703 hddTdlsPeer_t *pTdlsPeer;
6704 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
6705 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
6706 {
6707 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6708 "%s: %02x:%02x:%02x:%02x:%02x:%02x already connected. Request declined.",
6709 __func__, peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6710 return -EPERM;
6711 }
6712 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006713 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006714 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006715
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006716#ifdef WLAN_FEATURE_TDLS_DEBUG
6717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6718 "%s: %02x:%02x:%02x:%02x:%02x:%02x) action %d, dialog_token %d status %d, len = %d",
6719 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6720 action_code, dialog_token, status_code, len);
6721#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006722
Hoonki Leea34dd892013-02-05 22:56:02 -08006723 /*Except teardown responder will not be used so just make 0*/
6724 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006725 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08006726 {
6727 responder = wlan_hdd_tdls_get_responder(peerMac);
Pervinder Singhb4638422013-03-04 22:51:36 -08006728 if (-1 == responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08006729 {
6730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6731 "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
6732 "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
6733 dialog_token, status_code, len);
6734 return -EPERM;
6735 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006736 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006737
Pervinder Singhb4638422013-03-04 22:51:36 -08006738 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006739 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
6740 wlan_hdd_tdls_set_connection_progress(peer, TRUE);
6741
6742 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
6743
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006744 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08006745 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006746
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006747 if (VOS_STATUS_SUCCESS != status)
6748 {
6749 if(ret == 0 && /* if failure, don't need to set the progress bit */
6750 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
6751 wlan_hdd_tdls_set_connection_progress(peer, FALSE);
6752
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6754 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006755 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006756 }
6757
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006758 /* not block discovery request, as it is called from timer callback */
6759 if (SIR_MAC_TDLS_DIS_REQ != action_code)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006760 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006761 long rc;
6762
6763 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006764 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006765
Pervinder Singhb4638422013-03-04 22:51:36 -08006766 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006767 {
Pervinder Singhb4638422013-03-04 22:51:36 -08006768 if (ret == 0 && /* if failure, don't need to set the progress bit */
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006769 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
6770 wlan_hdd_tdls_set_connection_progress(peer, FALSE);
6771
6772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pervinder Singhb4638422013-03-04 22:51:36 -08006773 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
6774 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08006775 return -EPERM;
6776 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006777 }
6778
6779 if (ret)
6780 return ret;
6781
Hoonki Leea34dd892013-02-05 22:56:02 -08006782 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
6783 {
6784 wlan_hdd_tdls_set_responder(peerMac, TRUE);
6785 }
6786 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
6787 {
6788 wlan_hdd_tdls_set_responder(peerMac, FALSE);
6789 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006790
6791 return 0;
6792}
6793
6794static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
6795 u8 *peer, enum nl80211_tdls_operation oper)
6796{
6797 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6798 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006799#ifdef WLAN_FEATURE_TDLS_DEBUG
6800 const char *tdls_oper_str[]= {
6801 "NL80211_TDLS_DISCOVERY_REQ",
6802 "NL80211_TDLS_SETUP",
6803 "NL80211_TDLS_TEARDOWN",
6804 "NL80211_TDLS_ENABLE_LINK",
6805 "NL80211_TDLS_DISABLE_LINK",
6806 "NL80211_TDLS_UNKONW_OPER"};
6807#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006808
6809 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
6810 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006812 "Invalid arguments");
6813 return -EINVAL;
6814 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006815
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006816 if (pHddCtx->isLogpInProgress)
6817 {
6818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6819 "%s:LOGP in Progress. Ignore!!!", __func__);
6820 return -EBUSY;
6821 }
6822
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006823#ifdef WLAN_FEATURE_TDLS_DEBUG
6824 if((int)oper > 4)
6825 oper = 5;
6826
6827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6828 "%s: %02x:%02x:%02x:%02x:%02x:%02x: %d (%s) ", "tdls_oper",
6829 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5], (int)oper,
6830 tdls_oper_str[(int)oper]);
6831#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006832
6833 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006834 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006835 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08006836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006837 "TDLS Disabled in INI OR not enabled in FW.\
6838 Cannot process TDLS commands \n");
6839 return -ENOTSUPP;
6840 }
6841
6842 switch (oper) {
6843 case NL80211_TDLS_ENABLE_LINK:
6844 {
Hoonki Lee387663d2013-02-05 18:08:43 -08006845 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006846 VOS_STATUS status;
6847
6848 if (peer) {
Hoonki Lee387663d2013-02-05 18:08:43 -08006849 pTdlsPeer = wlan_hdd_tdls_find_peer(peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006850
6851 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Hoonki Lee387663d2013-02-05 18:08:43 -08006852 "%s: TDLS_LINK_ENABLE %2x:%2x:%2x:%2x:%2x:%2x",
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006853 __func__, peer[0], peer[1],
6854 peer[2], peer[3],
6855 peer[4], peer[5] );
6856
Hoonki Lee387663d2013-02-05 18:08:43 -08006857 if ( NULL == pTdlsPeer ) {
6858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer %2x:%2x:%2x:%2x:%2x:%2x failed",
6859 __func__, peer[0], peer[1],
6860 peer[2], peer[3],
6861 peer[4], peer[5] );
Hoonki Leef63df0d2013-01-16 19:29:14 -08006862 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006863 }
6864
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006865 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
6866 {
6867 /* start TDLS client registration with TL */
6868 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
6869 wlan_hdd_tdls_increment_peer_count();
6870 wlan_hdd_tdls_set_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
6871 wlan_hdd_tdls_check_bmps(pHddCtx);
6872 wlan_hdd_tdls_set_connection_progress(peer, FALSE);
6873 }
Chilam NG571c65a2013-01-19 12:27:36 +05306874
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006875 } else {
6876 hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
6877 }
6878 }
6879 break;
6880 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08006881 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006882 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(peer);
6883
6884 if(NULL != curr_peer)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006885 {
6886 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
6887 pAdapter->sessionId, peer );
Gopichand Nakkala901e8922013-03-04 23:45:58 -08006888 wlan_hdd_tdls_set_link_status(curr_peer, eTDLS_LINK_IDLE);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006889 curr_peer->isTDLSInProgress = FALSE;
Lee Hoonkic1262f22013-01-24 21:59:00 -08006890 }
6891 else
6892 {
6893 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6894 "%s: TDLS Peer Station doesn't exist \n",__func__);
6895 }
6896 return 0;
6897 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006898 case NL80211_TDLS_TEARDOWN:
6899 case NL80211_TDLS_SETUP:
6900 case NL80211_TDLS_DISCOVERY_REQ:
6901 /* We don't support in-driver setup/teardown/discovery */
6902 return -ENOTSUPP;
6903 default:
6904 return -ENOTSUPP;
6905 }
6906 return 0;
6907}
Chilam NG571c65a2013-01-19 12:27:36 +05306908
6909int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
6910 struct net_device *dev, u8 *peer)
6911{
6912 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
6913 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
6914
6915 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
6916 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
6917}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006918#endif
6919
Jeff Johnson295189b2012-06-20 16:38:30 -07006920/* cfg80211_ops */
6921static struct cfg80211_ops wlan_hdd_cfg80211_ops =
6922{
6923 .add_virtual_intf = wlan_hdd_add_virtual_intf,
6924 .del_virtual_intf = wlan_hdd_del_virtual_intf,
6925 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
6926 .change_station = wlan_hdd_change_station,
6927#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6928 .add_beacon = wlan_hdd_cfg80211_add_beacon,
6929 .del_beacon = wlan_hdd_cfg80211_del_beacon,
6930 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006931#else
6932 .start_ap = wlan_hdd_cfg80211_start_ap,
6933 .change_beacon = wlan_hdd_cfg80211_change_beacon,
6934 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07006935#endif
6936 .change_bss = wlan_hdd_cfg80211_change_bss,
6937 .add_key = wlan_hdd_cfg80211_add_key,
6938 .get_key = wlan_hdd_cfg80211_get_key,
6939 .del_key = wlan_hdd_cfg80211_del_key,
6940 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006941#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08006943#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 .scan = wlan_hdd_cfg80211_scan,
6945 .connect = wlan_hdd_cfg80211_connect,
6946 .disconnect = wlan_hdd_cfg80211_disconnect,
6947 .join_ibss = wlan_hdd_cfg80211_join_ibss,
6948 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
6949 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
6950 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
6951 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
6952#ifdef WLAN_FEATURE_P2P
6953 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
6954 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
6955 .mgmt_tx = wlan_hdd_action,
6956#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6957 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
6958 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
6959 .set_txq_params = wlan_hdd_set_txq_params,
6960#endif
6961#endif
6962 .get_station = wlan_hdd_cfg80211_get_station,
6963 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
6964 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006965 .add_station = wlan_hdd_cfg80211_add_station,
6966#ifdef FEATURE_WLAN_LFR
6967 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
6968 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
6969 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
6970#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006971#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6972 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
6973#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006974#ifdef FEATURE_WLAN_TDLS
6975 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
6976 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
6977#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006978};
6979
6980#endif // CONFIG_CFG80211