blob: ab4c9d0707605dba4a80fcad08da6e8a0dcd6267 [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
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070055
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070057
58
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070059 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070061
62
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070063 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070064
65
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070066 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070067 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070068 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070069
70 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070071 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070072 ==========================================================================*/
73
Jeff Johnson295189b2012-06-20 16:38:30 -070074
75#include <linux/version.h>
76#include <linux/module.h>
77#include <linux/kernel.h>
78#include <linux/init.h>
79#include <linux/wireless.h>
80#include <wlan_hdd_includes.h>
81#include <net/arp.h>
82#include <net/cfg80211.h>
83#include <linux/wireless.h>
84#include <wlan_hdd_wowl.h>
85#include <aniGlobal.h>
86#include "ccmApi.h"
87#include "sirParams.h"
88#include "dot11f.h"
89#include "wlan_hdd_assoc.h"
90#include "wlan_hdd_wext.h"
91#include "sme_Api.h"
92#include "wlan_hdd_p2p.h"
93#include "wlan_hdd_cfg80211.h"
94#include "wlan_hdd_hostapd.h"
95#include "sapInternal.h"
96#include "wlan_hdd_softap_tx_rx.h"
97#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053098#include "wlan_hdd_assoc.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099#ifdef WLAN_BTAMP_FEATURE
100#include "bap_hdd_misc.h"
101#endif
102#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800103#ifdef FEATURE_WLAN_TDLS
104#include "wlan_hdd_tdls.h"
105#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +0530106#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define g_mode_rates_size (12)
109#define a_mode_rates_size (8)
110#define FREQ_BASE_80211G (2407)
111#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700112#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
114 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
115
116#define HDD2GHZCHAN(freq, chan, flag) { \
117 .band = IEEE80211_BAND_2GHZ, \
118 .center_freq = (freq), \
119 .hw_value = (chan),\
120 .flags = (flag), \
121 .max_antenna_gain = 0 ,\
122 .max_power = 30, \
123}
124
125#define HDD5GHZCHAN(freq, chan, flag) { \
126 .band = IEEE80211_BAND_5GHZ, \
127 .center_freq = (freq), \
128 .hw_value = (chan),\
129 .flags = (flag), \
130 .max_antenna_gain = 0 ,\
131 .max_power = 30, \
132}
133
134#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
135{\
136 .bitrate = rate, \
137 .hw_value = rate_id, \
138 .flags = flag, \
139}
140
Lee Hoonkic1262f22013-01-24 21:59:00 -0800141#ifndef WLAN_FEATURE_TDLS_DEBUG
142#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
143#else
144#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
145#endif
146
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530147#ifdef WLAN_FEATURE_VOWIFI_11R
148#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
149#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
150#endif
151
Jeff Johnson295189b2012-06-20 16:38:30 -0700152static const u32 hdd_cipher_suites[] =
153{
154 WLAN_CIPHER_SUITE_WEP40,
155 WLAN_CIPHER_SUITE_WEP104,
156 WLAN_CIPHER_SUITE_TKIP,
157#ifdef FEATURE_WLAN_CCX
158#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
159 WLAN_CIPHER_SUITE_KRK,
160 WLAN_CIPHER_SUITE_CCMP,
161#else
162 WLAN_CIPHER_SUITE_CCMP,
163#endif
164#ifdef FEATURE_WLAN_WAPI
165 WLAN_CIPHER_SUITE_SMS4,
166#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700167#ifdef WLAN_FEATURE_11W
168 WLAN_CIPHER_SUITE_AES_CMAC,
169#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700170};
171
172static inline int is_broadcast_ether_addr(const u8 *addr)
173{
174 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
175 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
176}
177
178static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
179{
180 HDD2GHZCHAN(2412, 1, 0) ,
181 HDD2GHZCHAN(2417, 2, 0) ,
182 HDD2GHZCHAN(2422, 3, 0) ,
183 HDD2GHZCHAN(2427, 4, 0) ,
184 HDD2GHZCHAN(2432, 5, 0) ,
185 HDD2GHZCHAN(2437, 6, 0) ,
186 HDD2GHZCHAN(2442, 7, 0) ,
187 HDD2GHZCHAN(2447, 8, 0) ,
188 HDD2GHZCHAN(2452, 9, 0) ,
189 HDD2GHZCHAN(2457, 10, 0) ,
190 HDD2GHZCHAN(2462, 11, 0) ,
191 HDD2GHZCHAN(2467, 12, 0) ,
192 HDD2GHZCHAN(2472, 13, 0) ,
193 HDD2GHZCHAN(2484, 14, 0) ,
194};
195
Jeff Johnson295189b2012-06-20 16:38:30 -0700196static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
197{
198 HDD2GHZCHAN(2412, 1, 0) ,
199 HDD2GHZCHAN(2437, 6, 0) ,
200 HDD2GHZCHAN(2462, 11, 0) ,
201};
Jeff Johnson295189b2012-06-20 16:38:30 -0700202
203static struct ieee80211_channel hdd_channels_5_GHZ[] =
204{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700205 HDD5GHZCHAN(4920, 240, 0) ,
206 HDD5GHZCHAN(4940, 244, 0) ,
207 HDD5GHZCHAN(4960, 248, 0) ,
208 HDD5GHZCHAN(4980, 252, 0) ,
209 HDD5GHZCHAN(5040, 208, 0) ,
210 HDD5GHZCHAN(5060, 212, 0) ,
211 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 HDD5GHZCHAN(5180, 36, 0) ,
213 HDD5GHZCHAN(5200, 40, 0) ,
214 HDD5GHZCHAN(5220, 44, 0) ,
215 HDD5GHZCHAN(5240, 48, 0) ,
216 HDD5GHZCHAN(5260, 52, 0) ,
217 HDD5GHZCHAN(5280, 56, 0) ,
218 HDD5GHZCHAN(5300, 60, 0) ,
219 HDD5GHZCHAN(5320, 64, 0) ,
220 HDD5GHZCHAN(5500,100, 0) ,
221 HDD5GHZCHAN(5520,104, 0) ,
222 HDD5GHZCHAN(5540,108, 0) ,
223 HDD5GHZCHAN(5560,112, 0) ,
224 HDD5GHZCHAN(5580,116, 0) ,
225 HDD5GHZCHAN(5600,120, 0) ,
226 HDD5GHZCHAN(5620,124, 0) ,
227 HDD5GHZCHAN(5640,128, 0) ,
228 HDD5GHZCHAN(5660,132, 0) ,
229 HDD5GHZCHAN(5680,136, 0) ,
230 HDD5GHZCHAN(5700,140, 0) ,
231 HDD5GHZCHAN(5745,149, 0) ,
232 HDD5GHZCHAN(5765,153, 0) ,
233 HDD5GHZCHAN(5785,157, 0) ,
234 HDD5GHZCHAN(5805,161, 0) ,
235 HDD5GHZCHAN(5825,165, 0) ,
236};
237
238static struct ieee80211_rate g_mode_rates[] =
239{
240 HDD_G_MODE_RATETAB(10, 0x1, 0),
241 HDD_G_MODE_RATETAB(20, 0x2, 0),
242 HDD_G_MODE_RATETAB(55, 0x4, 0),
243 HDD_G_MODE_RATETAB(110, 0x8, 0),
244 HDD_G_MODE_RATETAB(60, 0x10, 0),
245 HDD_G_MODE_RATETAB(90, 0x20, 0),
246 HDD_G_MODE_RATETAB(120, 0x40, 0),
247 HDD_G_MODE_RATETAB(180, 0x80, 0),
248 HDD_G_MODE_RATETAB(240, 0x100, 0),
249 HDD_G_MODE_RATETAB(360, 0x200, 0),
250 HDD_G_MODE_RATETAB(480, 0x400, 0),
251 HDD_G_MODE_RATETAB(540, 0x800, 0),
252};
253
254static struct ieee80211_rate a_mode_rates[] =
255{
256 HDD_G_MODE_RATETAB(60, 0x10, 0),
257 HDD_G_MODE_RATETAB(90, 0x20, 0),
258 HDD_G_MODE_RATETAB(120, 0x40, 0),
259 HDD_G_MODE_RATETAB(180, 0x80, 0),
260 HDD_G_MODE_RATETAB(240, 0x100, 0),
261 HDD_G_MODE_RATETAB(360, 0x200, 0),
262 HDD_G_MODE_RATETAB(480, 0x400, 0),
263 HDD_G_MODE_RATETAB(540, 0x800, 0),
264};
265
266static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
267{
268 .channels = hdd_channels_2_4_GHZ,
269 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
270 .band = IEEE80211_BAND_2GHZ,
271 .bitrates = g_mode_rates,
272 .n_bitrates = g_mode_rates_size,
273 .ht_cap.ht_supported = 1,
274 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
275 | IEEE80211_HT_CAP_GRN_FLD
276 | IEEE80211_HT_CAP_DSSSCCK40
277 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
278 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
279 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
280 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
281 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
282 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
283};
284
Jeff Johnson295189b2012-06-20 16:38:30 -0700285static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
286{
287 .channels = hdd_social_channels_2_4_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
289 .band = IEEE80211_BAND_2GHZ,
290 .bitrates = g_mode_rates,
291 .n_bitrates = g_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
297 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
298 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
299 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
300 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
301 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
302};
Jeff Johnson295189b2012-06-20 16:38:30 -0700303
304static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
305{
306 .channels = hdd_channels_5_GHZ,
307 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
308 .band = IEEE80211_BAND_5GHZ,
309 .bitrates = a_mode_rates,
310 .n_bitrates = a_mode_rates_size,
311 .ht_cap.ht_supported = 1,
312 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
313 | IEEE80211_HT_CAP_GRN_FLD
314 | IEEE80211_HT_CAP_DSSSCCK40
315 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
316 | IEEE80211_HT_CAP_SGI_40
317 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
318 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
319 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
320 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
321 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
322 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
323};
324
325/* This structure contain information what kind of frame are expected in
326 TX/RX direction for each kind of interface */
327static const struct ieee80211_txrx_stypes
328wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
329 [NL80211_IFTYPE_STATION] = {
330 .tx = 0xffff,
331 .rx = BIT(SIR_MAC_MGMT_ACTION) |
332 BIT(SIR_MAC_MGMT_PROBE_REQ),
333 },
334 [NL80211_IFTYPE_AP] = {
335 .tx = 0xffff,
336 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
337 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
338 BIT(SIR_MAC_MGMT_PROBE_REQ) |
339 BIT(SIR_MAC_MGMT_DISASSOC) |
340 BIT(SIR_MAC_MGMT_AUTH) |
341 BIT(SIR_MAC_MGMT_DEAUTH) |
342 BIT(SIR_MAC_MGMT_ACTION),
343 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 [NL80211_IFTYPE_P2P_CLIENT] = {
345 .tx = 0xffff,
346 .rx = BIT(SIR_MAC_MGMT_ACTION) |
347 BIT(SIR_MAC_MGMT_PROBE_REQ),
348 },
349 [NL80211_IFTYPE_P2P_GO] = {
350 /* This is also same as for SoftAP */
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700360};
361
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800362#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800363static 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
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800418
Jeff Johnson295189b2012-06-20 16:38:30 -0700419static struct cfg80211_ops wlan_hdd_cfg80211_ops;
420
421/* Data rate 100KBPS based on IE Index */
422struct index_data_rate_type
423{
424 v_U8_t beacon_rate_index;
425 v_U16_t supported_rate[4];
426};
427
428/* 11B, 11G Rate table include Basic rate and Extended rate
429 The IDX field is the rate index
430 The HI field is the rate when RSSI is strong or being ignored
431 (in this case we report actual rate)
432 The MID field is the rate when RSSI is moderate
433 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
434 The LO field is the rate when RSSI is low
435 (in this case we don't report rates, actual current rate used)
436 */
437static const struct
438{
439 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700440 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700441} supported_data_rate[] =
442{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700443/* IDX HI HM LM LO (RSSI-based index */
444 {2, { 10, 10, 10, 0}},
445 {4, { 20, 20, 10, 0}},
446 {11, { 55, 20, 10, 0}},
447 {12, { 60, 55, 20, 0}},
448 {18, { 90, 55, 20, 0}},
449 {22, {110, 55, 20, 0}},
450 {24, {120, 90, 60, 0}},
451 {36, {180, 120, 60, 0}},
452 {44, {220, 180, 60, 0}},
453 {48, {240, 180, 90, 0}},
454 {66, {330, 180, 90, 0}},
455 {72, {360, 240, 90, 0}},
456 {96, {480, 240, 120, 0}},
457 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700458};
459
460/* MCS Based rate table */
461static struct index_data_rate_type supported_mcs_rate[] =
462{
463/* MCS L20 L40 S20 S40 */
464 {0, {65, 135, 72, 150}},
465 {1, {130, 270, 144, 300}},
466 {2, {195, 405, 217, 450}},
467 {3, {260, 540, 289, 600}},
468 {4, {390, 810, 433, 900}},
469 {5, {520, 1080, 578, 1200}},
470 {6, {585, 1215, 650, 1350}},
471 {7, {650, 1350, 722, 1500}}
472};
473
Leo Chang6f8870f2013-03-26 18:11:36 -0700474#ifdef WLAN_FEATURE_11AC
475
476#define DATA_RATE_11AC_MCS_MASK 0x0F
477
478struct index_vht_data_rate_type
479{
480 v_U8_t beacon_rate_index;
481 v_U16_t supported_rate[2];
482};
483
484typedef enum
485{
486 DATA_RATE_11AC_MAX_MCS_7,
487 DATA_RATE_11AC_MAX_MCS_8,
488 DATA_RATE_11AC_MAX_MCS_9,
489 DATA_RATE_11AC_MAX_MCS_NA
490} eDataRate11ACMaxMcs;
491
492/* MCS Based VHT rate table */
493static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
494{
495/* MCS L80 S80 */
496 {0, {293, 325}},
497 {1, {585, 650}},
498 {2, {878, 975}},
499 {3, {1170, 1300}},
500 {4, {1755, 1950}},
501 {5, {2340, 2600}},
502 {6, {2633, 2925}},
503 {7, {2925, 3250}},
504 {8, {3510, 3900}},
505 {9, {3900, 4333}}
506};
507#endif /* WLAN_FEATURE_11AC */
508
Jeff Johnson295189b2012-06-20 16:38:30 -0700509extern struct net_device_ops net_ops_struct;
510
511/*
512 * FUNCTION: wlan_hdd_cfg80211_init
513 * This function is called by hdd_wlan_startup()
514 * during initialization.
515 * This function is used to initialize and register wiphy structure.
516 */
517struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
518{
519 struct wiphy *wiphy;
520 ENTER();
521
522 /*
523 * Create wiphy device
524 */
525 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
526
527 if (!wiphy)
528 {
529 /* Print error and jump into err label and free the memory */
530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
531 return NULL;
532 }
533
534 return wiphy;
535}
536
537/*
538 * FUNCTION: wlan_hdd_cfg80211_update_band
539 * This function is called from the supplicant through a
540 * private ioctl to change the band value
541 */
542int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
543{
Jeff Johnsone7245742012-09-05 17:12:55 -0700544 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700545 switch(eBand)
546 {
547 case eCSR_BAND_24:
548 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
549 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
550 break;
551 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700552 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700553 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
554 break;
555 case eCSR_BAND_ALL:
556 default:
557 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
558 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
559 }
560 return 0;
561}
562/*
563 * FUNCTION: wlan_hdd_cfg80211_init
564 * This function is called by hdd_wlan_startup()
565 * during initialization.
566 * This function is used to initialize and register wiphy structure.
567 */
568int wlan_hdd_cfg80211_register(struct device *dev,
569 struct wiphy *wiphy,
570 hdd_config_t *pCfg
571 )
572{
Jeff Johnsone7245742012-09-05 17:12:55 -0700573 ENTER();
574
Jeff Johnson295189b2012-06-20 16:38:30 -0700575 /* Now bind the underlying wlan device with wiphy */
576 set_wiphy_dev(wiphy, dev);
577
578 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
579
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700580 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700581
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700583 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
584 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
585 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700586 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700587#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700588#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
589 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800590#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700591 || pCfg->isFastRoamIniFeatureEnabled
592#endif
593#ifdef FEATURE_WLAN_CCX
594 || pCfg->isCcxIniFeatureEnabled
595#endif
596 )
597 {
598 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
599 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800600#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800601#ifdef FEATURE_WLAN_TDLS
602 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
603 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
604#endif
605
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700606 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
607 driver can still register regulatory callback and
608 it will get CRDA setting in wiphy->band[], but
609 driver need to determine what to do with both
610 regulatory settings */
611 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700612
Jeff Johnson295189b2012-06-20 16:38:30 -0700613 wiphy->max_scan_ssids = MAX_SCAN_SSID;
614
615 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
616
617 /* Supports STATION & AD-HOC modes right now */
618 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
619 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700620 | BIT(NL80211_IFTYPE_P2P_CLIENT)
621 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 | BIT(NL80211_IFTYPE_AP);
623
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800625 if( pCfg->enableMCC )
626 {
627 /* Currently, supports up to two channels */
628 wlan_hdd_iface_combination.num_different_channels = 2;
629
630 if( !pCfg->allowMCCGODiffBI )
631 wlan_hdd_iface_combination.beacon_int_infra_match = true;
632
633 }
634 wiphy->iface_combinations = &wlan_hdd_iface_combination;
635 wiphy->n_iface_combinations = 1;
636#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800637
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 /* Before registering we need to update the ht capabilitied based
639 * on ini values*/
640 if( !pCfg->ShortGI20MhzEnable )
641 {
642 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
643 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
644 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
645 }
646
647 if( !pCfg->ShortGI40MhzEnable )
648 {
649 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
650 }
651
652 if( !pCfg->nChannelBondingMode5GHz )
653 {
654 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
655 }
656
657 /*Initialize band capability*/
658 switch(pCfg->nBandCapability)
659 {
660 case eCSR_BAND_24:
661 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
662 break;
663 case eCSR_BAND_5G:
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700665 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
666 break;
667 case eCSR_BAND_ALL:
668 default:
669 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
670 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
671 }
672 /*Initialise the supported cipher suite details*/
673 wiphy->cipher_suites = hdd_cipher_suites;
674 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
675
676 /*signal strength in mBm (100*dBm) */
677 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
678
679#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700680 wiphy->max_remain_on_channel_duration = 1000;
681#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700682
683 /* Register our wiphy dev with cfg80211 */
684 if (0 > wiphy_register(wiphy))
685 {
686 /* print eror */
687 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
688 return -EIO;
689 }
690
691 EXIT();
692 return 0;
693}
694
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700695/* In this function we will try to get default country code from crda.
696 If the gCrdaDefaultCountryCode is configured in ini file,
697 we will try to call user space crda to get the regulatory settings for
698 that country. We will timeout if we can't get it from crda.
699 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
700*/
701int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
702{
703 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
704 if (memcmp(pCfg->crdaDefaultCountryCode,
705 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
706 {
707 init_completion(&pHddCtx->driver_crda_req);
708 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
709 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
710 CRDA_WAIT_TIME);
711 }
712 return 0;
713}
714
Jeff Johnson295189b2012-06-20 16:38:30 -0700715/* In this function we will do all post VOS start initialization.
716 In this function we will register for all frame in which supplicant
717 is interested.
718*/
719void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
720{
Jeff Johnson295189b2012-06-20 16:38:30 -0700721 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
722 /* Register for all P2P action, public action etc frames */
723 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
724
Jeff Johnsone7245742012-09-05 17:12:55 -0700725 ENTER();
726
Jeff Johnson295189b2012-06-20 16:38:30 -0700727 /* Right now we are registering these frame when driver is getting
728 initialized. Once we will move to 2.6.37 kernel, in which we have
729 frame register ops, we will move this code as a part of that */
730 /* GAS Initial Request */
731 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
732 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
733
734 /* GAS Initial Response */
735 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
736 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
737
738 /* GAS Comeback Request */
739 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
740 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
741
742 /* GAS Comeback Response */
743 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
744 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
745
746 /* P2P Public Action */
747 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
748 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
749 P2P_PUBLIC_ACTION_FRAME_SIZE );
750
751 /* P2P Action */
752 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
753 (v_U8_t*)P2P_ACTION_FRAME,
754 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700755
756#ifdef WLAN_FEATURE_11W
757 /* SA Query Response Action Frame */
758 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
759 (v_U8_t*)SA_QUERY_FRAME_RSP,
760 SA_QUERY_FRAME_RSP_SIZE );
761#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700762}
763
764void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
765{
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
767 /* Register for all P2P action, public action etc frames */
768 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
769
Jeff Johnsone7245742012-09-05 17:12:55 -0700770 ENTER();
771
Jeff Johnson295189b2012-06-20 16:38:30 -0700772 /* Right now we are registering these frame when driver is getting
773 initialized. Once we will move to 2.6.37 kernel, in which we have
774 frame register ops, we will move this code as a part of that */
775 /* GAS Initial Request */
776
777 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
778 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
779
780 /* GAS Initial Response */
781 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
782 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
783
784 /* GAS Comeback Request */
785 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
786 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
787
788 /* GAS Comeback Response */
789 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
790 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
791
792 /* P2P Public Action */
793 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
794 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
795 P2P_PUBLIC_ACTION_FRAME_SIZE );
796
797 /* P2P Action */
798 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
799 (v_U8_t*)P2P_ACTION_FRAME,
800 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700801
802#ifdef WLAN_FEATURE_11W
803 /* SA Query Response Action Frame */
804 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
805 (v_U8_t*)SA_QUERY_FRAME_RSP,
806 SA_QUERY_FRAME_RSP_SIZE );
807#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700808}
809
810#ifdef FEATURE_WLAN_WAPI
811void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
812 const u8 *mac_addr, u8 *key , int key_Len)
813{
814 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
815 tCsrRoamSetKey setKey;
816 v_BOOL_t isConnected = TRUE;
817 int status = 0;
818 v_U32_t roamId= 0xFF;
819 tANI_U8 *pKeyPtr = NULL;
820 int n = 0;
821
822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
823 __func__,pAdapter->device_mode);
824
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530825 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 setKey.keyId = key_index; // Store Key ID
827 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
828 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
829 setKey.paeRole = 0 ; // the PAE role
830 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
831 {
832 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
833 }
834 else
835 {
836 isConnected = hdd_connIsConnected(pHddStaCtx);
837 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
838 }
839 setKey.keyLength = key_Len;
840 pKeyPtr = setKey.Key;
841 memcpy( pKeyPtr, key, key_Len);
842
843 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
844 __func__, key_Len);
845 for (n = 0 ; n < key_Len; n++)
846 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
847 __func__,n,setKey.Key[n]);
848
849 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
850 if ( isConnected )
851 {
852 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
853 pAdapter->sessionId, &setKey, &roamId );
854 }
855 if ( status != 0 )
856 {
857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
858 "[%4d] sme_RoamSetKey returned ERROR status= %d",
859 __LINE__, status );
860 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
861 }
862}
863#endif /* FEATURE_WLAN_WAPI*/
864
865#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
866int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
867 beacon_data_t **ppBeacon,
868 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700869#else
870int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
871 beacon_data_t **ppBeacon,
872 struct cfg80211_beacon_data *params,
873 int dtim_period)
874#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700875{
876 int size;
877 beacon_data_t *beacon = NULL;
878 beacon_data_t *old = NULL;
879 int head_len,tail_len;
880
Jeff Johnsone7245742012-09-05 17:12:55 -0700881 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 if (params->head && !params->head_len)
883 return -EINVAL;
884
885 old = pAdapter->sessionCtx.ap.beacon;
886
887 if (!params->head && !old)
888 return -EINVAL;
889
890 if (params->tail && !params->tail_len)
891 return -EINVAL;
892
893#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
894 /* Kernel 3.0 is not updating dtim_period for set beacon */
895 if (!params->dtim_period)
896 return -EINVAL;
897#endif
898
899 if(params->head)
900 head_len = params->head_len;
901 else
902 head_len = old->head_len;
903
904 if(params->tail || !old)
905 tail_len = params->tail_len;
906 else
907 tail_len = old->tail_len;
908
909 size = sizeof(beacon_data_t) + head_len + tail_len;
910
911 beacon = kzalloc(size, GFP_KERNEL);
912
913 if( beacon == NULL )
914 return -ENOMEM;
915
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700916#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700917 if(params->dtim_period || !old )
918 beacon->dtim_period = params->dtim_period;
919 else
920 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700921#else
922 if(dtim_period || !old )
923 beacon->dtim_period = dtim_period;
924 else
925 beacon->dtim_period = old->dtim_period;
926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700927
928 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
929 beacon->tail = beacon->head + head_len;
930 beacon->head_len = head_len;
931 beacon->tail_len = tail_len;
932
933 if(params->head) {
934 memcpy (beacon->head,params->head,beacon->head_len);
935 }
936 else {
937 if(old)
938 memcpy (beacon->head,old->head,beacon->head_len);
939 }
940
941 if(params->tail) {
942 memcpy (beacon->tail,params->tail,beacon->tail_len);
943 }
944 else {
945 if(old)
946 memcpy (beacon->tail,old->tail,beacon->tail_len);
947 }
948
949 *ppBeacon = beacon;
950
951 kfree(old);
952
953 return 0;
954
955}
Jeff Johnson295189b2012-06-20 16:38:30 -0700956
957v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
958{
959 int left = length;
960 v_U8_t *ptr = pIes;
961 v_U8_t elem_id,elem_len;
962
963 while(left >= 2)
964 {
965 elem_id = ptr[0];
966 elem_len = ptr[1];
967 left -= 2;
968 if(elem_len > left)
969 {
970 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700971 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 eid,elem_len,left);
973 return NULL;
974 }
975 if (elem_id == eid)
976 {
977 return ptr;
978 }
979
980 left -= elem_len;
981 ptr += (elem_len + 2);
982 }
983 return NULL;
984}
985
Jeff Johnson295189b2012-06-20 16:38:30 -0700986/* Check if rate is 11g rate or not */
987static int wlan_hdd_rate_is_11g(u8 rate)
988{
989 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
990 u8 i;
991 for (i = 0; i < 8; i++)
992 {
993 if(rate == gRateArray[i])
994 return TRUE;
995 }
996 return FALSE;
997}
998
999/* Check for 11g rate and set proper 11g only mode */
1000static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1001 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1002{
1003 u8 i, num_rates = pIe[0];
1004
1005 pIe += 1;
1006 for ( i = 0; i < num_rates; i++)
1007 {
1008 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1009 {
1010 /* If rate set have 11g rate than change the mode to 11G */
1011 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1012 if (pIe[i] & BASIC_RATE_MASK)
1013 {
1014 /* If we have 11g rate as basic rate, it means mode
1015 is 11g only mode.
1016 */
1017 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1018 *pCheckRatesfor11g = FALSE;
1019 }
1020 }
1021 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1022 {
1023 *require_ht = TRUE;
1024 }
1025 }
1026 return;
1027}
1028
1029static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1030{
1031 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1032 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1033 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1034 u8 checkRatesfor11g = TRUE;
1035 u8 require_ht = FALSE;
1036 u8 *pIe=NULL;
1037
1038 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1039
1040 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1041 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1042 if (pIe != NULL)
1043 {
1044 pIe += 1;
1045 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1046 &pConfig->SapHw_mode);
1047 }
1048
1049 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1050 WLAN_EID_EXT_SUPP_RATES);
1051 if (pIe != NULL)
1052 {
1053
1054 pIe += 1;
1055 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1056 &pConfig->SapHw_mode);
1057 }
1058
1059 if( pConfig->channel > 14 )
1060 {
1061 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1062 }
1063
1064 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1065 WLAN_EID_HT_CAPABILITY);
1066
1067 if(pIe)
1068 {
1069 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1070 if(require_ht)
1071 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1072 }
1073}
1074
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301075static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1076 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1077{
1078 v_U8_t ielen = 0;
1079 v_U8_t *pIe = NULL;
1080 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1081
1082 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1083 pBeacon->tail, pBeacon->tail_len);
1084
1085 if (pIe)
1086 {
1087 ielen = pIe[1] + 2;
1088 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1089 {
1090 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1091 }
1092 else
1093 {
1094 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1095 return -EINVAL;
1096 }
1097 *total_ielen += ielen;
1098 }
1099 return 0;
1100}
1101
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001102#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001103static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1104 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001105#else
1106static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1107 struct cfg80211_beacon_data *params)
1108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001109{
1110 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301111 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001113 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001114
1115 genie = vos_mem_malloc(MAX_GENIE_LEN);
1116
1117 if(genie == NULL) {
1118
1119 return -ENOMEM;
1120 }
1121
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301122 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1123 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301125 ret = -EINVAL;
1126 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 }
1128
1129#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301130 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1131 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1132 {
1133 ret = -EINVAL;
1134 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 }
1136#endif
1137
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301138 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1139 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301141 ret = -EINVAL;
1142 goto done;
1143 }
1144
1145 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1146 {
1147 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1148 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301150 ret = -EINVAL;
1151 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001154
1155 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1156 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1157 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1158 {
1159 hddLog(LOGE,
1160 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001161 ret = -EINVAL;
1162 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 }
1164
1165 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1166 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1167 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1168 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1169 ==eHAL_STATUS_FAILURE)
1170 {
1171 hddLog(LOGE,
1172 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001173 ret = -EINVAL;
1174 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 }
1176
1177 // Added for ProResp IE
1178 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1179 {
1180 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1181 u8 probe_rsp_ie_len[3] = {0};
1182 u8 counter = 0;
1183 /* Check Probe Resp Length if it is greater then 255 then Store
1184 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1185 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1186 Store More then 255 bytes into One Variable.
1187 */
1188 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1189 {
1190 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1191 {
1192 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1193 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1194 }
1195 else
1196 {
1197 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1198 rem_probe_resp_ie_len = 0;
1199 }
1200 }
1201
1202 rem_probe_resp_ie_len = 0;
1203
1204 if (probe_rsp_ie_len[0] > 0)
1205 {
1206 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1207 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1208 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1209 probe_rsp_ie_len[0], NULL,
1210 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1211 {
1212 hddLog(LOGE,
1213 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001214 ret = -EINVAL;
1215 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001216 }
1217 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1218 }
1219
1220 if (probe_rsp_ie_len[1] > 0)
1221 {
1222 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1223 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1224 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1225 probe_rsp_ie_len[1], NULL,
1226 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1227 {
1228 hddLog(LOGE,
1229 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001230 ret = -EINVAL;
1231 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 }
1233 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1234 }
1235
1236 if (probe_rsp_ie_len[2] > 0)
1237 {
1238 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1239 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1240 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1241 probe_rsp_ie_len[2], NULL,
1242 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1243 {
1244 hddLog(LOGE,
1245 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001246 ret = -EINVAL;
1247 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001248 }
1249 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1250 }
1251
1252 if (probe_rsp_ie_len[1] == 0 )
1253 {
1254 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1255 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1256 eANI_BOOLEAN_FALSE) )
1257 {
1258 hddLog(LOGE,
1259 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1260 }
1261 }
1262
1263 if (probe_rsp_ie_len[2] == 0 )
1264 {
1265 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1266 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1267 eANI_BOOLEAN_FALSE) )
1268 {
1269 hddLog(LOGE,
1270 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1271 }
1272 }
1273
1274 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1275 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1276 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1277 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1278 == eHAL_STATUS_FAILURE)
1279 {
1280 hddLog(LOGE,
1281 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001282 ret = -EINVAL;
1283 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 }
1285 }
1286 else
1287 {
1288 // Reset WNI_CFG_PROBE_RSP Flags
1289 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1290
1291 hddLog(VOS_TRACE_LEVEL_INFO,
1292 "%s: No Probe Response IE received in set beacon",
1293 __func__);
1294 }
1295
1296 // Added for AssocResp IE
1297 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1298 {
1299 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1300 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1301 params->assocresp_ies_len, NULL,
1302 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1303 {
1304 hddLog(LOGE,
1305 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001306 ret = -EINVAL;
1307 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 }
1309
1310 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1311 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1312 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1313 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1314 == eHAL_STATUS_FAILURE)
1315 {
1316 hddLog(LOGE,
1317 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001318 ret = -EINVAL;
1319 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001320 }
1321 }
1322 else
1323 {
1324 hddLog(VOS_TRACE_LEVEL_INFO,
1325 "%s: No Assoc Response IE received in set beacon",
1326 __func__);
1327
1328 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1329 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1330 eANI_BOOLEAN_FALSE) )
1331 {
1332 hddLog(LOGE,
1333 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1334 }
1335 }
1336
Jeff Johnsone7245742012-09-05 17:12:55 -07001337done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301339 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001340}
Jeff Johnson295189b2012-06-20 16:38:30 -07001341
1342/*
1343 * FUNCTION: wlan_hdd_validate_operation_channel
1344 * called by wlan_hdd_cfg80211_start_bss() and
1345 * wlan_hdd_cfg80211_set_channel()
1346 * This function validates whether given channel is part of valid
1347 * channel list.
1348 */
1349static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1350{
1351
1352 v_U32_t num_ch = 0;
1353 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1354 u32 indx = 0;
1355 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301356 v_U8_t fValidChannel = FALSE, count = 0;
1357 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07001358
1359 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1360
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301361 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301363 /* Validate the channel */
1364 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001365 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301366 if ( channel == rfChannels[count].channelNum )
1367 {
1368 fValidChannel = TRUE;
1369 break;
1370 }
1371 }
1372 if (fValidChannel != TRUE)
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 "%s: Invalid Channel [%d]", __func__, channel);
1376 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001377 }
1378 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301379 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001380 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301381 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1382 valid_ch, &num_ch))
1383 {
1384 hddLog(VOS_TRACE_LEVEL_ERROR,
1385 "%s: failed to get valid channel list", __func__);
1386 return VOS_STATUS_E_FAILURE;
1387 }
1388 for (indx = 0; indx < num_ch; indx++)
1389 {
1390 if (channel == valid_ch[indx])
1391 {
1392 break;
1393 }
1394 }
1395
1396 if (indx >= num_ch)
1397 {
1398 hddLog(VOS_TRACE_LEVEL_ERROR,
1399 "%s: Invalid Channel [%d]", __func__, channel);
1400 return VOS_STATUS_E_FAILURE;
1401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 }
1403 return VOS_STATUS_SUCCESS;
1404
1405}
1406
Viral Modi3a32cc52013-02-08 11:14:52 -08001407/**
1408 * FUNCTION: wlan_hdd_cfg80211_set_channel
1409 * This function is used to set the channel number
1410 */
1411static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1412 struct ieee80211_channel *chan,
1413 enum nl80211_channel_type channel_type
1414 )
1415{
1416 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001417 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001418 hdd_adapter_t *pAdapter = NULL;
1419 int freq = chan->center_freq; /* freq is in MHZ */
1420
1421 ENTER();
1422
1423 if( NULL == dev )
1424 {
1425 hddLog(VOS_TRACE_LEVEL_ERROR,
1426 "%s: Called with dev = NULL.\n", __func__);
1427 return -ENODEV;
1428 }
1429 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1430
1431 hddLog(VOS_TRACE_LEVEL_INFO,
1432 "%s: device_mode = %d freq = %d \n",__func__,
1433 pAdapter->device_mode, chan->center_freq);
1434 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1435 {
1436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1437 return -EAGAIN;
1438 }
1439
1440 /*
1441 * Do freq to chan conversion
1442 * TODO: for 11a
1443 */
1444
1445 channel = ieee80211_frequency_to_channel(freq);
1446
1447 /* Check freq range */
1448 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1449 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1450 {
1451 hddLog(VOS_TRACE_LEVEL_ERROR,
1452 "%s: Channel [%d] is outside valid range from %d to %d\n",
1453 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1454 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1455 return -EINVAL;
1456 }
1457
1458 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1459
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301460 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1461 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001462 {
1463 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1464 {
1465 hddLog(VOS_TRACE_LEVEL_ERROR,
1466 "%s: Invalid Channel [%d] \n", __func__, channel);
1467 return -EINVAL;
1468 }
1469 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1470 "%s: set channel to [%d] for device mode =%d",
1471 __func__, channel,pAdapter->device_mode);
1472 }
1473 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001474 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001475 )
1476 {
1477 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1478 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1479 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1480
1481 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1482 {
1483 /* Link is up then return cant set channel*/
1484 hddLog( VOS_TRACE_LEVEL_ERROR,
1485 "%s: IBSS Associated, can't set the channel\n", __func__);
1486 return -EINVAL;
1487 }
1488
1489 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1490 pHddStaCtx->conn_info.operationChannel = channel;
1491 pRoamProfile->ChannelInfo.ChannelList =
1492 &pHddStaCtx->conn_info.operationChannel;
1493 }
1494 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001495 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001496 )
1497 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301498 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1499 {
1500 if(VOS_STATUS_SUCCESS !=
1501 wlan_hdd_validate_operation_channel(pAdapter,channel))
1502 {
1503 hddLog(VOS_TRACE_LEVEL_ERROR,
1504 "%s: Invalid Channel [%d] \n", __func__, channel);
1505 return -EINVAL;
1506 }
1507 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1508 }
1509 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001510 {
1511 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1512
1513 /* If auto channel selection is configured as enable/ 1 then ignore
1514 channel set by supplicant
1515 */
1516 if ( cfg_param->apAutoChannelSelection )
1517 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301518 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1519 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001520 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1521 "%s: set channel to auto channel (0) for device mode =%d",
1522 __func__, pAdapter->device_mode);
1523 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301524 else
1525 {
1526 if(VOS_STATUS_SUCCESS !=
1527 wlan_hdd_validate_operation_channel(pAdapter,channel))
1528 {
1529 hddLog(VOS_TRACE_LEVEL_ERROR,
1530 "%s: Invalid Channel [%d] \n", __func__, channel);
1531 return -EINVAL;
1532 }
1533 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1534 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001535 }
1536 }
1537 else
1538 {
1539 hddLog(VOS_TRACE_LEVEL_FATAL,
1540 "%s: Invalid device mode failed to set valid channel", __func__);
1541 return -EINVAL;
1542 }
1543 EXIT();
1544 return 0;
1545}
1546
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301547/*
1548 * FUNCTION: wlan_hdd_select_cbmode
1549 * called by wlan_hdd_cfg80211_start_bss() and
1550 * This function selects the cbmode based on primary channel
1551 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001552VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301553{
1554 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001555 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1556 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
1557
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301558 if(
1559#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001560 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1561 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301562#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001563 SapHw_mode != eSAP_DOT11_MODE_11n &&
1564 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301565 )
1566 {
1567 return VOS_STATUS_SUCCESS;
1568 }
1569
1570 if (!pConfigIni->nChannelBondingMode5GHz) {
1571 return VOS_STATUS_SUCCESS;
1572 }
1573
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001574 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301575 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1576
1577 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1578
1579#ifdef WLAN_FEATURE_11AC
1580
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001581 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
1582 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301583 {
1584 if ( channel== 36 || channel == 52 || channel == 100 ||
1585 channel == 116 || channel == 149 )
1586 {
1587 smeConfig.csrConfig.channelBondingMode5GHz =
1588 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1589 }
1590 else if ( channel == 40 || channel == 56 || channel == 104 ||
1591 channel == 120 || channel == 153 )
1592 {
1593 smeConfig.csrConfig.channelBondingMode5GHz =
1594 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1595 }
1596 else if ( channel == 44 || channel == 60 || channel == 108 ||
1597 channel == 124 || channel == 157 )
1598 {
1599 smeConfig.csrConfig.channelBondingMode5GHz =
1600 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1601 }
1602 else if ( channel == 48 || channel == 64 || channel == 112 ||
1603 channel == 128 || channel == 161 )
1604 {
1605 smeConfig.csrConfig.channelBondingMode5GHz =
1606 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1607 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001608 else if ( channel == 165 )
1609 {
1610 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1611 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301612 }
1613#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001614 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1615 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301616 {
1617 if ( channel== 40 || channel == 48 || channel == 56 ||
1618 channel == 64 || channel == 104 || channel == 112 ||
1619 channel == 120 || channel == 128 || channel == 136 ||
1620 channel == 144 || channel == 153 || channel == 161 )
1621 {
1622 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1623 }
1624 else if ( channel== 36 || channel == 44 || channel == 52 ||
1625 channel == 60 || channel == 100 || channel == 108 ||
1626 channel == 116 || channel == 124 || channel == 132 ||
1627 channel == 140 || channel == 149 || channel == 157 )
1628 {
1629 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1630 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001631 else if ( channel == 165 )
1632 {
1633 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1634 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301635 }
1636 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1637
1638 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1639 return VOS_STATUS_SUCCESS;
1640}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001641
Jeff Johnson295189b2012-06-20 16:38:30 -07001642#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1643static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1644 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001645#else
1646static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1647 struct cfg80211_beacon_data *params,
1648 const u8 *ssid, size_t ssid_len,
1649 enum nl80211_hidden_ssid hidden_ssid)
1650#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001651{
1652 tsap_Config_t *pConfig;
1653 beacon_data_t *pBeacon = NULL;
1654 struct ieee80211_mgmt *pMgmt_frame;
1655 v_U8_t *pIe=NULL;
1656 v_U16_t capab_info;
1657 eCsrAuthType RSNAuthType;
1658 eCsrEncryptionType RSNEncryptType;
1659 eCsrEncryptionType mcRSNEncryptType;
1660 int status = VOS_STATUS_SUCCESS;
1661 tpWLAN_SAPEventCB pSapEventCallback;
1662 hdd_hostapd_state_t *pHostapdState;
1663 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1664 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301665 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001666 struct qc_mac_acl_entry *acl_entry = NULL;
1667 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001668 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001669
1670 ENTER();
1671
1672 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1673
1674 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1675
1676 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1677
1678 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1679
1680 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1681
1682 //channel is already set in the set_channel Call back
1683 //pConfig->channel = pCommitConfig->channel;
1684
1685 /*Protection parameter to enable or disable*/
1686 pConfig->protEnabled =
1687 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1688
1689 pConfig->dtim_period = pBeacon->dtim_period;
1690
1691 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1692 pConfig->dtim_period);
1693
1694
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001695 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001696 {
1697 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001699 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001700 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001701 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001702 pConfig->ieee80211d = 1;
1703 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1704 sme_setRegInfo(hHal, pConfig->countryCode);
1705 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001707 else
1708 {
1709 pConfig->ieee80211d = 0;
1710 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301711 /*
1712 * If auto channel is configured i.e. channel is 0,
1713 * so skip channel validation.
1714 */
1715 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1716 {
1717 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1718 {
1719 hddLog(VOS_TRACE_LEVEL_ERROR,
1720 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1721 return -EINVAL;
1722 }
1723 }
1724 else
1725 {
1726 if(1 != pHddCtx->is_dynamic_channel_range_set)
1727 {
1728 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1729 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1730 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1731 }
1732 pHddCtx->is_dynamic_channel_range_set = 0;
1733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001734 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001735 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 {
1737 pConfig->ieee80211d = 0;
1738 }
1739 pConfig->authType = eSAP_AUTO_SWITCH;
1740
1741 capab_info = pMgmt_frame->u.beacon.capab_info;
1742
1743 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
1744 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1745
1746 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1747
1748 /*Set wps station to configured*/
1749 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1750
1751 if(pIe)
1752 {
1753 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1754 {
1755 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1756 return -EINVAL;
1757 }
1758 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1759 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001760 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 /* Check 15 bit of WPS IE as it contain information for wps state
1762 * WPS state
1763 */
1764 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1765 {
1766 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1767 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1768 {
1769 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1770 }
1771 }
1772 }
1773 else
1774 {
1775 pConfig->wps_state = SAP_WPS_DISABLED;
1776 }
1777 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1778
1779 pConfig->RSNWPAReqIELength = 0;
1780 pConfig->pRSNWPAReqIE = NULL;
1781 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1782 WLAN_EID_RSN);
1783 if(pIe && pIe[1])
1784 {
1785 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1786 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1787 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1788 /* The actual processing may eventually be more extensive than
1789 * this. Right now, just consume any PMKIDs that are sent in
1790 * by the app.
1791 * */
1792 status = hdd_softap_unpackIE(
1793 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1794 &RSNEncryptType,
1795 &mcRSNEncryptType,
1796 &RSNAuthType,
1797 pConfig->pRSNWPAReqIE[1]+2,
1798 pConfig->pRSNWPAReqIE );
1799
1800 if( VOS_STATUS_SUCCESS == status )
1801 {
1802 /* Now copy over all the security attributes you have
1803 * parsed out
1804 * */
1805 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1806 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1807 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1808 = RSNEncryptType;
1809 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1810 "EncryptionType = %d mcEncryptionType = %d\n"),
1811 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1812 }
1813 }
1814
1815 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1816 pBeacon->tail, pBeacon->tail_len);
1817
1818 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1819 {
1820 if (pConfig->pRSNWPAReqIE)
1821 {
1822 /*Mixed mode WPA/WPA2*/
1823 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1824 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1825 }
1826 else
1827 {
1828 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1829 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1830 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
1831 status = hdd_softap_unpackIE(
1832 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1833 &RSNEncryptType,
1834 &mcRSNEncryptType,
1835 &RSNAuthType,
1836 pConfig->pRSNWPAReqIE[1]+2,
1837 pConfig->pRSNWPAReqIE );
1838
1839 if( VOS_STATUS_SUCCESS == status )
1840 {
1841 /* Now copy over all the security attributes you have
1842 * parsed out
1843 * */
1844 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1845 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1846 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1847 = RSNEncryptType;
1848 hddLog( LOG1, FL("%s: CSR AuthType = %d, "
1849 "EncryptionType = %d mcEncryptionType = %d\n"),
1850 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1851 }
1852 }
1853 }
1854
Jeff Johnson4416a782013-03-25 14:17:50 -07001855 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1856 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1857 return -EINVAL;
1858 }
1859
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1861
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001862#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 if (params->ssid != NULL)
1864 {
1865 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1866 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1867 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1868 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1869 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001870#else
1871 if (ssid != NULL)
1872 {
1873 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1874 pConfig->SSIDinfo.ssid.length = ssid_len;
1875 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1876 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1877 }
1878#endif
1879
Jeff Johnson295189b2012-06-20 16:38:30 -07001880 vos_mem_copy(pConfig->self_macaddr.bytes,
1881 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1882
1883 /* default value */
1884 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1885 pConfig->num_accept_mac = 0;
1886 pConfig->num_deny_mac = 0;
1887
1888 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1889 pBeacon->tail, pBeacon->tail_len);
1890
1891 /* pIe for black list is following form:
1892 type : 1 byte
1893 length : 1 byte
1894 OUI : 4 bytes
1895 acl type : 1 byte
1896 no of mac addr in black list: 1 byte
1897 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1898 */
1899 if ((pIe != NULL) && (pIe[1] != 0))
1900 {
1901 pConfig->SapMacaddr_acl = pIe[6];
1902 pConfig->num_deny_mac = pIe[7];
1903 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1904 pIe[6], pIe[7]);
1905 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1906 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1907 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1908 for (i = 0; i < pConfig->num_deny_mac; i++)
1909 {
1910 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1911 acl_entry++;
1912 }
1913 }
1914 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1915 pBeacon->tail, pBeacon->tail_len);
1916
1917 /* pIe for white list is following form:
1918 type : 1 byte
1919 length : 1 byte
1920 OUI : 4 bytes
1921 acl type : 1 byte
1922 no of mac addr in white list: 1 byte
1923 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
1924 */
1925 if ((pIe != NULL) && (pIe[1] != 0))
1926 {
1927 pConfig->SapMacaddr_acl = pIe[6];
1928 pConfig->num_accept_mac = pIe[7];
1929 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1930 pIe[6], pIe[7]);
1931 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1932 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1933 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1934 for (i = 0; i < pConfig->num_accept_mac; i++)
1935 {
1936 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1937 acl_entry++;
1938 }
1939 }
1940 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1941
Jeff Johnsone7245742012-09-05 17:12:55 -07001942#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001943 /* Overwrite the hostapd setting for HW mode only for 11ac.
1944 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1945 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1946 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1947 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
1948 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
1949 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1950 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001951 {
1952 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1953 }
1954#endif
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301955
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001956 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1957 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 // ht_capab is not what the name conveys,this is used for protection bitmap
1959 pConfig->ht_capab =
1960 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1961
1962 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1963 {
1964 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1965 return -EINVAL;
1966 }
1967
1968 //Uapsd Enabled Bit
1969 pConfig->UapsdEnable =
1970 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1971 //Enable OBSS protection
1972 pConfig->obssProtEnabled =
1973 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1974
1975 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
1976 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1977 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1978 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1979 (int)pConfig->channel);
1980 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1981 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1982 pConfig->authType);
1983 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1984 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1985 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1986 pConfig->protEnabled, pConfig->obssProtEnabled);
1987
1988 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
1989 {
1990 //Bss already started. just return.
1991 //TODO Probably it should update some beacon params.
1992 hddLog( LOGE, "Bss Already started...Ignore the request");
1993 EXIT();
1994 return 0;
1995 }
1996
1997 pConfig->persona = pHostapdAdapter->device_mode;
1998
1999 pSapEventCallback = hdd_hostapd_SAPEventCB;
2000 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2001 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2002 {
2003 hddLog(LOGE,FL("SAP Start Bss fail\n"));
2004 return -EINVAL;
2005 }
2006
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002007 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2009
2010 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2011
2012 if (!VOS_IS_STATUS_SUCCESS(status))
2013 {
2014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2015 ("ERROR: HDD vos wait for single_event failed!!\n"));
2016 VOS_ASSERT(0);
2017 }
2018
2019 //Succesfully started Bss update the state bit.
2020 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2021
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002022#ifdef WLAN_FEATURE_P2P_DEBUG
2023 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2024 {
2025 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2026 {
2027 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2028 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002029 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002030 }
2031 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2032 {
2033 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2034 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002035 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002036 }
2037 }
2038#endif
2039
Jeff Johnson295189b2012-06-20 16:38:30 -07002040 pHostapdState->bCommit = TRUE;
2041 EXIT();
2042
2043 return 0;
2044}
2045
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002046#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002047static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2048 struct net_device *dev,
2049 struct beacon_parameters *params)
2050{
2051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2052 int status=VOS_STATUS_SUCCESS;
2053
2054 ENTER();
2055
2056 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2057
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002058 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2059 {
2060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2061 "%s:LOGP in Progress. Ignore!!!", __func__);
2062 return -EAGAIN;
2063 }
2064
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 )
2068 {
2069 beacon_data_t *old,*new;
2070
2071 old = pAdapter->sessionCtx.ap.beacon;
2072
2073 if (old)
2074 return -EALREADY;
2075
2076 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2077
2078 if(status != VOS_STATUS_SUCCESS)
2079 {
2080 hddLog(VOS_TRACE_LEVEL_FATAL,
2081 "%s:Error!!! Allocating the new beacon\n",__func__);
2082 return -EINVAL;
2083 }
2084
2085 pAdapter->sessionCtx.ap.beacon = new;
2086
2087 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2088 }
2089
2090 EXIT();
2091 return status;
2092}
2093
2094static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
2095 struct net_device *dev,
2096 struct beacon_parameters *params)
2097{
2098 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2099 int status=VOS_STATUS_SUCCESS;
2100
2101 ENTER();
2102
2103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2104 __func__,pAdapter->device_mode);
2105
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002106 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2107 {
2108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2109 "%s:LOGP in Progress. Ignore!!!", __func__);
2110 return -EAGAIN;
2111 }
2112
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 )
2116 {
2117 beacon_data_t *old,*new;
2118
2119 old = pAdapter->sessionCtx.ap.beacon;
2120
2121 if (!old)
2122 return -ENOENT;
2123
2124 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2125
2126 if(status != VOS_STATUS_SUCCESS) {
2127 hddLog(VOS_TRACE_LEVEL_FATAL,
2128 "%s: Error!!! Allocating the new beacon\n",__func__);
2129 return -EINVAL;
2130 }
2131
2132 pAdapter->sessionCtx.ap.beacon = new;
2133
2134 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2135 }
2136
2137 EXIT();
2138 return status;
2139}
2140
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002141#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2142
2143#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002144static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2145 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002146#else
2147static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2148 struct net_device *dev)
2149#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002150{
2151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002152 hdd_context_t *pHddCtx = NULL;
2153 hdd_scaninfo_t *pScanInfo = NULL;
2154 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 VOS_STATUS status = 0;
2156
2157 ENTER();
2158
2159 if (NULL == pAdapter)
2160 {
2161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002162 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002163 return -ENODEV;
2164 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002165
Jeff Johnson4416a782013-03-25 14:17:50 -07002166 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002167 if (NULL == pHddCtx)
2168 {
2169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002170 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002171 return -ENODEV;
2172 }
Jeff Johnson4416a782013-03-25 14:17:50 -07002173 if (pHddCtx->isLogpInProgress)
2174 {
2175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2176 "%s:LOGP in Progress. Ignore!!!", __func__);
2177 return -EAGAIN;
2178 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002179
2180 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2181 if (NULL == staAdapter)
2182 {
2183 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2184 if (NULL == staAdapter)
2185 {
2186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002187 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002188 return -ENODEV;
2189 }
2190 }
2191
2192 pScanInfo = &pHddCtx->scan_info;
2193
Jeff Johnson4416a782013-03-25 14:17:50 -07002194 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 {
2196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2197 return -EAGAIN;
2198 }
2199
2200 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2201
2202 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2203 __func__,pAdapter->device_mode);
2204
Jeff Johnsone7245742012-09-05 17:12:55 -07002205 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2206 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002207 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002208 hdd_abort_mac_scan(staAdapter->pHddCtx);
2209 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002210 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002211 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2212 if (!status)
2213 {
2214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002215 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002216 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002217 VOS_ASSERT(pScanInfo->mScanPending);
2218 return 0;
2219 }
2220 }
2221
Jeff Johnson295189b2012-06-20 16:38:30 -07002222 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002223 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002224 )
2225 {
2226 beacon_data_t *old;
2227
2228 old = pAdapter->sessionCtx.ap.beacon;
2229
2230 if (!old)
2231 return -ENOENT;
2232
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002234
2235 mutex_lock(&pHddCtx->sap_lock);
2236 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2237 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002238 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 {
2240 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2241
2242 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2243
2244 if (!VOS_IS_STATUS_SUCCESS(status))
2245 {
2246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2247 ("ERROR: HDD vos wait for single_event failed!!\n"));
2248 VOS_ASSERT(0);
2249 }
2250 }
2251 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2252 }
2253 mutex_unlock(&pHddCtx->sap_lock);
2254
2255 if(status != VOS_STATUS_SUCCESS)
2256 {
2257 hddLog(VOS_TRACE_LEVEL_FATAL,
2258 "%s:Error!!! Stopping the BSS\n",__func__);
2259 return -EINVAL;
2260 }
2261
Jeff Johnson4416a782013-03-25 14:17:50 -07002262 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2264 ==eHAL_STATUS_FAILURE)
2265 {
2266 hddLog(LOGE,
2267 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2268 }
2269
Jeff Johnson4416a782013-03-25 14:17:50 -07002270 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2272 eANI_BOOLEAN_FALSE) )
2273 {
2274 hddLog(LOGE,
2275 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2276 }
2277
2278 // Reset WNI_CFG_PROBE_RSP Flags
2279 wlan_hdd_reset_prob_rspies(pAdapter);
2280
2281 pAdapter->sessionCtx.ap.beacon = NULL;
2282 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002283#ifdef WLAN_FEATURE_P2P_DEBUG
2284 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2285 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2286 {
2287 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2288 "GO got removed");
2289 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2290 }
2291#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002292 }
2293 EXIT();
2294 return status;
2295}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002296
2297#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2298
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302299static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2300 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002301 struct cfg80211_ap_settings *params)
2302{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302303 hdd_adapter_t *pAdapter;
2304 hdd_context_t *pHddCtx;
2305 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002306
2307 ENTER();
2308
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302309 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002310 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2312 "%s: Device is Null", __func__);
2313 return -ENODEV;
2314 }
2315
2316 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2317 if (NULL == pAdapter)
2318 {
2319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2320 "%s: HDD adapter is Null", __func__);
2321 return -ENODEV;
2322 }
2323
2324 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2325 {
2326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2327 "%s: HDD adapter magic is invalid", __func__);
2328 return -ENODEV;
2329 }
2330
2331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2332 if (NULL == pHddCtx)
2333 {
2334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2335 "%s: HDD context is Null", __func__);
2336 return -ENODEV;
2337 }
2338
2339 if (pHddCtx->isLogpInProgress)
2340 {
2341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2342 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002343 return -EAGAIN;
2344 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302345
2346 if (pHddCtx->isLoadUnloadInProgress)
2347 {
2348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2349 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2350 return -EAGAIN;
2351 }
2352
2353 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2354 __func__, pAdapter->device_mode);
2355
2356 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002357 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002358 )
2359 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302360 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002361
2362 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302363
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364 if (old)
2365 return -EALREADY;
2366
2367 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2368
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302369 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002370 {
2371 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302372 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002373 return -EINVAL;
2374 }
2375 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002376#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2377 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2378#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002379 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2380 params->ssid_len, params->hidden_ssid);
2381 }
2382
2383 EXIT();
2384 return status;
2385}
2386
2387
2388static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
2389 struct net_device *dev,
2390 struct cfg80211_beacon_data *params)
2391{
2392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2393 int status=VOS_STATUS_SUCCESS;
2394
2395 ENTER();
2396
2397 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2398 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002399 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2400 {
2401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2402 return -EAGAIN;
2403 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002404
2405 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002406 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002407 )
2408 {
2409 beacon_data_t *old,*new;
2410
2411 old = pAdapter->sessionCtx.ap.beacon;
2412
2413 if (!old)
2414 return -ENOENT;
2415
2416 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2417
2418 if(status != VOS_STATUS_SUCCESS) {
2419 hddLog(VOS_TRACE_LEVEL_FATAL,
2420 "%s: Error!!! Allocating the new beacon\n",__func__);
2421 return -EINVAL;
2422 }
2423
2424 pAdapter->sessionCtx.ap.beacon = new;
2425
2426 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2427 }
2428
2429 EXIT();
2430 return status;
2431}
2432
2433#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2434
Jeff Johnson295189b2012-06-20 16:38:30 -07002435
2436static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2437 struct net_device *dev,
2438 struct bss_parameters *params)
2439{
2440 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2441
2442 ENTER();
2443
2444 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2445 __func__,pAdapter->device_mode);
2446
2447 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002448 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002449 )
2450 {
2451 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2452 * want to update this parameter */
2453 if (-1 != params->ap_isolate)
2454 {
2455 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
2456 }
2457 }
2458
2459 EXIT();
2460 return 0;
2461}
2462
2463/*
2464 * FUNCTION: wlan_hdd_cfg80211_change_iface
2465 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2466 */
2467int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2468 struct net_device *ndev,
2469 enum nl80211_iftype type,
2470 u32 *flags,
2471 struct vif_params *params
2472 )
2473{
2474 struct wireless_dev *wdev;
2475 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2476 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002477 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002478 tCsrRoamProfile *pRoamProfile = NULL;
2479 eCsrRoamBssType LastBSSType;
2480 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2481 eMib_dot11DesiredBssType connectedBssType;
2482 VOS_STATUS status;
2483
2484 ENTER();
2485
2486 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2487 {
2488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2489 return -EAGAIN;
2490 }
2491
2492 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2493 __func__, pAdapter->device_mode);
2494
2495 wdev = ndev->ieee80211_ptr;
2496
2497#ifdef WLAN_BTAMP_FEATURE
2498 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2499 (NL80211_IFTYPE_ADHOC == type)||
2500 (NL80211_IFTYPE_AP == type)||
2501 (NL80211_IFTYPE_P2P_GO == type))
2502 {
2503 pHddCtx->isAmpAllowed = VOS_FALSE;
2504 // stop AMP traffic
2505 status = WLANBAP_StopAmp();
2506 if(VOS_STATUS_SUCCESS != status )
2507 {
2508 pHddCtx->isAmpAllowed = VOS_TRUE;
2509 hddLog(VOS_TRACE_LEVEL_FATAL,
2510 "%s: Failed to stop AMP", __func__);
2511 return -EINVAL;
2512 }
2513 }
2514#endif //WLAN_BTAMP_FEATURE
2515 /* Reset the current device mode bit mask*/
2516 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2517
2518 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002519 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002520 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002521 )
2522 {
2523 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2524 pRoamProfile = &pWextState->roamProfile;
2525 LastBSSType = pRoamProfile->BSSType;
2526
2527 switch (type)
2528 {
2529 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002531 hddLog(VOS_TRACE_LEVEL_INFO,
2532 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2533 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002534#ifdef WLAN_FEATURE_11AC
2535 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2536 {
2537 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2538 }
2539#endif
2540 pRoamProfile->phyMode =
2541 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002542 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002543 //Check for sub-string p2p to confirm its a p2p interface
2544 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002545 {
2546 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2547 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2548 }
2549 else
2550 {
2551 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002552 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002553 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 break;
2555 case NL80211_IFTYPE_ADHOC:
2556 hddLog(VOS_TRACE_LEVEL_INFO,
2557 "%s: setting interface Type to ADHOC", __func__);
2558 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2559 pRoamProfile->phyMode =
2560 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2561 wdev->iftype = type;
2562 break;
2563
2564 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002565 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002566 {
2567 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2568 "%s: setting interface Type to %s", __func__,
2569 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2570
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002571 //Cancel any remain on channel for GO mode
2572 if (NL80211_IFTYPE_P2P_GO == type)
2573 {
2574 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2575 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002576 if (NL80211_IFTYPE_AP == type)
2577 {
2578 /* As Loading WLAN Driver one interface being created for p2p device
2579 * address. This will take one HW STA and the max number of clients
2580 * that can connect to softAP will be reduced by one. so while changing
2581 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2582 * interface as it is not required in SoftAP mode.
2583 */
2584
2585 // Get P2P Adapter
2586 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2587
2588 if (pP2pAdapter)
2589 {
2590 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2591 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2592 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2593 }
2594 }
2595
Jeff Johnson295189b2012-06-20 16:38:30 -07002596 //De-init the adapter.
2597 hdd_stop_adapter( pHddCtx, pAdapter );
2598 hdd_deinit_adapter( pHddCtx, pAdapter );
2599 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002600 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2601 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002602
2603 //Disable BMPS and IMPS if enabled
2604 //before starting Go
2605 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2606 {
2607 if(VOS_STATUS_E_FAILURE ==
2608 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2609 {
2610 //Fail to Exit BMPS
2611 VOS_ASSERT(0);
2612 }
2613 }
2614
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002615 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2616 (pConfig->apRandomBssidEnabled))
2617 {
2618 /* To meet Android requirements create a randomized
2619 MAC address of the form 02:1A:11:Fx:xx:xx */
2620 get_random_bytes(&ndev->dev_addr[3], 3);
2621 ndev->dev_addr[0] = 0x02;
2622 ndev->dev_addr[1] = 0x1A;
2623 ndev->dev_addr[2] = 0x11;
2624 ndev->dev_addr[3] |= 0xF0;
2625 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2626 VOS_MAC_ADDR_SIZE);
2627 pr_info("wlan: Generated HotSpot BSSID "
2628 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2629 ndev->dev_addr[0],
2630 ndev->dev_addr[1],
2631 ndev->dev_addr[2],
2632 ndev->dev_addr[3],
2633 ndev->dev_addr[4],
2634 ndev->dev_addr[5]);
2635 }
2636
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 hdd_set_ap_ops( pAdapter->dev );
2638
2639 status = hdd_init_ap_mode(pAdapter);
2640 if(status != VOS_STATUS_SUCCESS)
2641 {
2642 hddLog(VOS_TRACE_LEVEL_FATAL,
2643 "%s: Error initializing the ap mode", __func__);
2644 return -EINVAL;
2645 }
2646 hdd_set_conparam(1);
2647
Jeff Johnson295189b2012-06-20 16:38:30 -07002648 /*interface type changed update in wiphy structure*/
2649 if(wdev)
2650 {
2651 wdev->iftype = type;
2652 pHddCtx->change_iface = type;
2653 }
2654 else
2655 {
2656 hddLog(VOS_TRACE_LEVEL_ERROR,
2657 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2658 return -EINVAL;
2659 }
2660 goto done;
2661 }
2662
2663 default:
2664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2665 __func__);
2666 return -EOPNOTSUPP;
2667 }
2668 }
2669 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002670 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002671 )
2672 {
2673 switch(type)
2674 {
2675 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002676 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002677 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002678 hdd_stop_adapter( pHddCtx, pAdapter );
2679 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002681 //Check for sub-string p2p to confirm its a p2p interface
2682 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002683 {
2684 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2685 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2686 }
2687 else
2688 {
2689 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002690 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002692 hdd_set_conparam(0);
2693 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002694 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2695 hdd_set_station_ops( pAdapter->dev );
2696 status = hdd_init_station_mode( pAdapter );
2697 if( VOS_STATUS_SUCCESS != status )
2698 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002699 /* In case of JB, for P2P-GO, only change interface will be called,
2700 * This is the right place to enable back bmps_imps()
2701 */
2702 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002703 goto done;
2704 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002705 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002706 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002707 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2708 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002709 goto done;
2710 default:
2711 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2712 __func__);
2713 return -EOPNOTSUPP;
2714
2715 }
2716
2717 }
2718 else
2719 {
2720 return -EOPNOTSUPP;
2721 }
2722
2723
2724 if(pRoamProfile)
2725 {
2726 if ( LastBSSType != pRoamProfile->BSSType )
2727 {
2728 /*interface type changed update in wiphy structure*/
2729 wdev->iftype = type;
2730
2731 /*the BSS mode changed, We need to issue disconnect
2732 if connected or in IBSS disconnect state*/
2733 if ( hdd_connGetConnectedBssType(
2734 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2735 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2736 {
2737 /*need to issue a disconnect to CSR.*/
2738 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2739 if( eHAL_STATUS_SUCCESS ==
2740 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2741 pAdapter->sessionId,
2742 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2743 {
2744 wait_for_completion_interruptible_timeout(
2745 &pAdapter->disconnect_comp_var,
2746 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2747 }
2748 }
2749 }
2750 }
2751
2752done:
2753 /*set bitmask based on updated value*/
2754 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2755#ifdef WLAN_BTAMP_FEATURE
2756 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
2757 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2758 {
2759 //we are ok to do AMP
2760 pHddCtx->isAmpAllowed = VOS_TRUE;
2761 }
2762#endif //WLAN_BTAMP_FEATURE
2763 EXIT();
2764 return 0;
2765}
2766
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002767#ifdef FEATURE_WLAN_TDLS
2768static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2769 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2770{
2771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2772 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2773 VOS_STATUS status;
2774
2775 ENTER();
2776
2777 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2780 "Invalid arguments");
2781 return -EINVAL;
2782 }
Hoonki Lee27511902013-03-14 18:19:06 -07002783
2784 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2785 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2786 {
2787 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2788 "%s: TDLS mode is disabled OR not enabled in FW."
2789 MAC_ADDRESS_STR " Request declined.",
2790 __func__, MAC_ADDR_ARRAY(mac));
2791 return -ENOTSUPP;
2792 }
2793
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002794 if (pHddCtx->isLogpInProgress)
2795 {
2796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2797 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002798 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002799 return -EBUSY;
2800 }
2801
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002802 /* when self is on-going, we dont' want to change link_status */
2803 if ((0 == update) && wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2804 {
2805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2806 "%s: " MAC_ADDRESS_STR
2807 " TDLS setup is ongoing. Request declined.",
2808 __func__, MAC_ADDR_ARRAY(mac));
2809 return -EPERM;
2810 }
2811
2812 /* when others are on-going, we want to change link_status to idle */
2813 if (wlan_hdd_tdls_is_progress(pAdapter, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002814 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2816 "%s: " MAC_ADDRESS_STR
2817 " TDLS setup is ongoing. Request declined.",
2818 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002819 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002820 }
2821
2822 /* first to check if we reached to maximum supported TDLS peer.
2823 TODO: for now, return -EPERM looks working fine,
2824 but need to check if any other errno fit into this category.*/
2825 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2826 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: " MAC_ADDRESS_STR
2829 " TDLS Max peer already connected. Request declined.",
2830 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002831 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002832 }
2833 else
2834 {
2835 hddTdlsPeer_t *pTdlsPeer;
2836 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2837 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
2838 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2840 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2841 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002842 return -EPERM;
2843 }
2844 }
2845
2846 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
2847
2848 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2849
2850 if (!update)
2851 {
2852 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2853 pAdapter->sessionId, mac);
2854 }
2855 else
2856 {
2857 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2858 pAdapter->sessionId, mac, StaParams);
2859 }
2860
2861 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2862 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2863
2864 if (!status)
2865 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002867 "%s: timeout waiting for tdls add station indication",
2868 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002869 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002870 }
2871 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2872 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002874 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002875 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002876 }
2877
2878 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002879
2880error:
2881 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2882 return -EPERM;
2883
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002884}
2885#endif
2886
Jeff Johnson295189b2012-06-20 16:38:30 -07002887static int wlan_hdd_change_station(struct wiphy *wiphy,
2888 struct net_device *dev,
2889 u8 *mac,
2890 struct station_parameters *params)
2891{
2892 VOS_STATUS status = VOS_STATUS_SUCCESS;
2893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2894 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002895#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002896 tCsrStaParams StaParams = {0};
2897 u32 set;
2898 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002899#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002900 ENTER();
2901
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002902 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2903 {
2904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2905 "%s:LOGP in Progress. Ignore!!!", __func__);
2906 return -EAGAIN;
2907 }
2908
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2910
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002911#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002912 StaParams.capability = params->capability;
2913 StaParams.uapsd_queues = params->uapsd_queues;
2914 StaParams.max_sp = params->max_sp;
2915
2916 if (0 != params->ext_capab_len)
2917 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2918 sizeof(StaParams.extn_capability));
2919
2920 if (NULL != params->ht_capa)
2921 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
2922
2923 StaParams.supported_rates_len = params->supported_rates_len;
2924
2925 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2926 * The supported_rates array , for all the structures propogating till Add Sta
2927 * to the firmware has to be modified , if the supplicant (ieee80211) is
2928 * modified to send more rates.
2929 */
2930
2931 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2932 */
2933 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2934 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2935
2936 if (0 != StaParams.supported_rates_len) {
2937 int i = 0;
2938 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2939 StaParams.supported_rates_len);
2940 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2941 "Supported Rates with Length %d", StaParams.supported_rates_len);
2942 for (i=0; i < StaParams.supported_rates_len; i++)
2943 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2944 "[%d]: %0x", i, StaParams.supported_rates[i]);
2945 }
2946
2947 if (NULL != params->vht_capa)
2948 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
2949
2950 set = params->sta_flags_set;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002951#endif
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002952
2953 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2954 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002956 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002957 {
2958 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
2959 WLANTL_STA_AUTHENTICATED);
2960
2961 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002962 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002963 return -EINVAL;
2964 }
2965 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002966#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002967 else if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ) {
2968 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2969 if (0 != params->ext_capab_len ) {
2970 /*Define A Macro : TODO Sunil*/
2971 if ((1<<4) & StaParams.extn_capability[3]) {
2972 isBufSta = 1;
2973 }
2974 }
2975 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2976 "%s: TDLS Peer Parameters.", __func__);
2977 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2978 "uapsd_queues: %0x\n", params->uapsd_queues);
2979 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2980 "max_sp: %0x\n", params->max_sp);
2981 if (params->ht_capa) {
2982 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2983 "ht_capa->cap_info: %0x\n", params->ht_capa->cap_info);
2984 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2985 "ht_capa->ampdu_params_info: %0x\n",
2986 params->ht_capa->ampdu_params_info);
2987 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2988 "ht_capa->extended_capabilities: %0x\n",
2989 params->ht_capa->extended_ht_cap_info);
2990 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2991 "ht_capa->tx_BF_cap_info: %0x\n",
2992 params->ht_capa->tx_BF_cap_info);
2993 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2994 "ht_capa->antenna_selection_info: %0x\n",
2995 params->ht_capa->antenna_selection_info);
2996 }
2997 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2998 "params->capability: %0x\n",params->capability);
2999 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3000 "params->ext_capab_len: %0x\n",params->ext_capab_len);
3001 if (0 != params->ext_capab_len )
3002 {
3003 int i =0;
3004 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3005 "Extended capabilities:");
3006 for (i=0; i < params->ext_capab_len; i++)
3007 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3008 "[%d]: %0x", i, params->ext_capab[i]);
3009 }
3010 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3011 // params->max_sp, isBufSta);
3012 if (VOS_STATUS_SUCCESS != status) {
3013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3014 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3015 return -EINVAL;
3016 }
3017 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3018 "ht_capa->cap_info: %0x\n", StaParams.HTCap.capInfo);
3019 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3020
3021 if (VOS_STATUS_SUCCESS != status) {
3022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3023 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3024 return -EINVAL;
3025 }
3026 }
3027 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003028#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003029
Jeff Johnsone7245742012-09-05 17:12:55 -07003030 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003031 return status;
3032}
3033
3034/*
3035 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
3036 * This function is used to get peer station index in IBSS mode
3037 */
3038static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
3039{
3040 u8 idx = 0;
3041 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
3042 ENTER();
3043 memset(temp, 0, VOS_MAC_ADDR_SIZE);
3044 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
3045 {
3046 if ( (0 !=
3047 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
3048 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
3049 temp, VOS_MAC_ADDR_SIZE)
3050 )
3051 {
3052 return idx;
3053 }
3054 }
3055 return idx;
3056}
3057
3058
3059/*
3060 * FUNCTION: wlan_hdd_cfg80211_add_key
3061 * This function is used to initialize the key information
3062 */
3063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003064static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003065 struct net_device *ndev,
3066 u8 key_index, bool pairwise,
3067 const u8 *mac_addr,
3068 struct key_params *params
3069 )
3070#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003071static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 struct net_device *ndev,
3073 u8 key_index, const u8 *mac_addr,
3074 struct key_params *params
3075 )
3076#endif
3077{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003078 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 tCsrRoamSetKey setKey;
3080 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3081 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003082 v_U32_t roamId= 0xFF;
3083 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003084 hdd_hostapd_state_t *pHostapdState;
3085 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003086 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003087
3088 ENTER();
3089
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003090 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3091 {
3092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3093 "%s:LOGP in Progress. Ignore!!!", __func__);
3094 return -EAGAIN;
3095 }
3096
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3098 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003099
3100 if (CSR_MAX_NUM_KEY <= key_index)
3101 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 key_index);
3104
3105 return -EINVAL;
3106 }
3107
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003108 if (CSR_MAX_KEY_LEN < params->key_len)
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3111 params->key_len);
3112
3113 return -EINVAL;
3114 }
3115
3116 hddLog(VOS_TRACE_LEVEL_INFO,
3117 "%s: called with key index = %d & key length %d",
3118 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 /*extract key idx, key len and key*/
3121 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3122 setKey.keyId = key_index;
3123 setKey.keyLength = params->key_len;
3124 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3125
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003126 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003127 {
3128 case WLAN_CIPHER_SUITE_WEP40:
3129 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3130 break;
3131
3132 case WLAN_CIPHER_SUITE_WEP104:
3133 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3134 break;
3135
3136 case WLAN_CIPHER_SUITE_TKIP:
3137 {
3138 u8 *pKey = &setKey.Key[0];
3139 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3140
3141 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3142
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003143 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003144
3145 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003146 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 |--------------|----------|----------|
3148 <---16bytes---><--8bytes--><--8bytes-->
3149
3150 */
3151 /*Sme expects the 32 bytes key to be in the below order
3152
3153 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003154 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 |--------------|----------|----------|
3156 <---16bytes---><--8bytes--><--8bytes-->
3157 */
3158 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003159 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003160
3161 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003162 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003163
3164 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003165 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003166
3167
3168 break;
3169 }
3170
3171 case WLAN_CIPHER_SUITE_CCMP:
3172 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3173 break;
3174
3175#ifdef FEATURE_WLAN_WAPI
3176 case WLAN_CIPHER_SUITE_SMS4:
3177 {
3178 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3179 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3180 params->key, params->key_len);
3181 return 0;
3182 }
3183#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003184
Jeff Johnson295189b2012-06-20 16:38:30 -07003185#ifdef FEATURE_WLAN_CCX
3186 case WLAN_CIPHER_SUITE_KRK:
3187 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3188 break;
3189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003190
3191#ifdef WLAN_FEATURE_11W
3192 case WLAN_CIPHER_SUITE_AES_CMAC:
3193 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
3194 /* Temporarily we will ignore the setting of the IGTK. Once the Riva
3195 firmware is modified to handle the IGTK, then we will proceeed normally.
3196 For now, we just return success. */
3197 return 0;
3198 /* break; */
3199#endif
3200
Jeff Johnson295189b2012-06-20 16:38:30 -07003201 default:
3202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3203 __func__, params->cipher);
3204 return -EOPNOTSUPP;
3205 }
3206
3207 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3208 __func__, setKey.encType);
3209
3210
3211
3212 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003213 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003214 )
3215 {
3216
3217
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003218 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3220 (!pairwise)
3221#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003222 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003223#endif
3224 )
3225 {
3226 /* set group key*/
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003228 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 __func__, __LINE__);
3230 setKey.keyDirection = eSIR_RX_ONLY;
3231 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3232 }
3233 else
3234 {
3235 /* set pairwise key*/
3236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3237 "%s- %d: setting pairwise key",
3238 __func__, __LINE__);
3239 setKey.keyDirection = eSIR_TX_RX;
3240 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3241 }
3242
3243 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003244 if( pHostapdState->bssState == BSS_START )
3245 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3247
3248 if ( status != eHAL_STATUS_SUCCESS )
3249 {
3250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3251 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3252 __LINE__, status );
3253 }
3254 }
3255
3256 /* Saving WEP keys */
3257 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3258 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3259 {
3260 //Save the wep key in ap context. Issue setkey after the BSS is started.
3261 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3262 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3263 }
3264 else
3265 {
3266 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003267 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003268 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3269 }
3270 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003271 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3272 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003273 {
3274 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3275 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3276
3277 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3278
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003279 pWextState->roamProfile.Keys.defaultIndex = key_index;
3280
3281
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003282 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003283 params->key, params->key_len);
3284
3285 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3286
3287 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3288 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3289 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3290 )
3291 &&
3292 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3293 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3294 )
3295 )
3296 {
3297 /* in case of static WEP, macaddr/bssid is not coming from nl80211
3298 * interface, copy bssid for pairwise key and group macaddr for
3299 * group key initialization*/
3300
3301 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3302
3303 pWextState->roamProfile.negotiatedUCEncryptionType =
3304 pHddStaCtx->conn_info.ucEncryptionType =
3305 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3306 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3307 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3308
3309
3310 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3311 "%s: Negotiated encryption type %d", __func__,
3312 pWextState->roamProfile.negotiatedUCEncryptionType);
3313
3314 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3315 &pWextState->roamProfile, true);
3316 setKey.keyLength = 0;
3317 setKey.keyDirection = eSIR_TX_RX;
3318
3319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3320 if (pairwise)
3321 {
3322#endif
3323 if (mac_addr)
3324 {
3325 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3326 }
3327 else
3328 {
3329 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
3330 * and peerMacAddress in case of IBSS*/
3331 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3332 {
3333 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3334 if (HDD_MAX_NUM_IBSS_STA != staidx)
3335 {
3336 vos_mem_copy(setKey.peerMac,
3337 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3338 WNI_CFG_BSSID_LEN);
3339
3340 }
3341 else
3342 {
3343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
3344 __func__);
3345 return -EOPNOTSUPP;
3346 }
3347 }
3348 else
3349 {
3350 vos_mem_copy(setKey.peerMac,
3351 &pHddStaCtx->conn_info.bssId[0],
3352 WNI_CFG_BSSID_LEN);
3353 }
3354 }
3355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3356 }
3357 else
3358 {
3359 /* set group key*/
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3361 "%s- %d: setting Group key",
3362 __func__, __LINE__);
3363 setKey.keyDirection = eSIR_RX_ONLY;
3364 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3365 }
3366#endif
3367 }
3368 else if (
3369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3370 (!pairwise)
3371#else
3372 (!mac_addr || is_broadcast_ether_addr(mac_addr))
3373#endif
3374 )
3375 {
3376 /* set group key*/
3377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3378 "%s- %d: setting Group key",
3379 __func__, __LINE__);
3380 setKey.keyDirection = eSIR_RX_ONLY;
3381 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3382 }
3383 else
3384 {
3385 /* set pairwise key*/
3386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3387 "%s- %d: setting pairwise key",
3388 __func__, __LINE__);
3389 setKey.keyDirection = eSIR_TX_RX;
3390 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3391 }
3392
3393 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3394 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3395 __func__, setKey.peerMac[0], setKey.peerMac[1],
3396 setKey.peerMac[2], setKey.peerMac[3],
3397 setKey.peerMac[4], setKey.peerMac[5],
3398 setKey.keyDirection);
3399
3400 vos_status = wlan_hdd_check_ula_done(pAdapter);
3401
3402 if ( vos_status != VOS_STATUS_SUCCESS )
3403 {
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3406 __LINE__, vos_status );
3407
3408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3409
3410 return -EINVAL;
3411
3412 }
3413
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003414#ifdef WLAN_FEATURE_VOWIFI_11R
3415 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3416 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003417 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303418 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003419 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303420 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003421 }
3422#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003423
3424 /* issue set key request to SME*/
3425 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3426 pAdapter->sessionId, &setKey, &roamId );
3427
3428 if ( 0 != status )
3429 {
3430 hddLog(VOS_TRACE_LEVEL_ERROR,
3431 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3432 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3433 return -EINVAL;
3434 }
3435
3436
3437 /* in case of IBSS as there was no information available about WEP keys during
3438 * IBSS join, group key intialized with NULL key, so re-initialize group key
3439 * with correct value*/
3440 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3441 !( ( IW_AUTH_KEY_MGMT_802_1X
3442 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
3443 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3444 )
3445 &&
3446 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3447 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3448 )
3449 )
3450 {
3451 setKey.keyDirection = eSIR_RX_ONLY;
3452 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3453
3454 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3455 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
3456 __func__, setKey.peerMac[0], setKey.peerMac[1],
3457 setKey.peerMac[2], setKey.peerMac[3],
3458 setKey.peerMac[4], setKey.peerMac[5],
3459 setKey.keyDirection);
3460
3461 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3462 pAdapter->sessionId, &setKey, &roamId );
3463
3464 if ( 0 != status )
3465 {
3466 hddLog(VOS_TRACE_LEVEL_ERROR,
3467 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
3468 __func__, status);
3469 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3470 return -EINVAL;
3471 }
3472 }
3473 }
3474
3475 return 0;
3476}
3477
3478/*
3479 * FUNCTION: wlan_hdd_cfg80211_get_key
3480 * This function is used to get the key information
3481 */
3482#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3483static int wlan_hdd_cfg80211_get_key(
3484 struct wiphy *wiphy,
3485 struct net_device *ndev,
3486 u8 key_index, bool pairwise,
3487 const u8 *mac_addr, void *cookie,
3488 void (*callback)(void *cookie, struct key_params*)
3489 )
3490#else
3491static int wlan_hdd_cfg80211_get_key(
3492 struct wiphy *wiphy,
3493 struct net_device *ndev,
3494 u8 key_index, const u8 *mac_addr, void *cookie,
3495 void (*callback)(void *cookie, struct key_params*)
3496 )
3497#endif
3498{
3499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3500 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3501 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3502 struct key_params params;
3503
3504 ENTER();
3505
3506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3507 __func__,pAdapter->device_mode);
3508
3509 memset(&params, 0, sizeof(params));
3510
3511 if (CSR_MAX_NUM_KEY <= key_index)
3512 {
3513 return -EINVAL;
3514 }
3515
3516 switch(pRoamProfile->EncryptionType.encryptionType[0])
3517 {
3518 case eCSR_ENCRYPT_TYPE_NONE:
3519 params.cipher = IW_AUTH_CIPHER_NONE;
3520 break;
3521
3522 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3523 case eCSR_ENCRYPT_TYPE_WEP40:
3524 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3525 break;
3526
3527 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3528 case eCSR_ENCRYPT_TYPE_WEP104:
3529 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3530 break;
3531
3532 case eCSR_ENCRYPT_TYPE_TKIP:
3533 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3534 break;
3535
3536 case eCSR_ENCRYPT_TYPE_AES:
3537 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3538 break;
3539
3540 default:
3541 params.cipher = IW_AUTH_CIPHER_NONE;
3542 break;
3543 }
3544
3545 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3546 params.seq_len = 0;
3547 params.seq = NULL;
3548 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3549 callback(cookie, &params);
3550 return 0;
3551}
3552
3553/*
3554 * FUNCTION: wlan_hdd_cfg80211_del_key
3555 * This function is used to delete the key information
3556 */
3557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3558static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3559 struct net_device *ndev,
3560 u8 key_index,
3561 bool pairwise,
3562 const u8 *mac_addr
3563 )
3564#else
3565static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
3566 struct net_device *ndev,
3567 u8 key_index,
3568 const u8 *mac_addr
3569 )
3570#endif
3571{
3572 int status = 0;
3573
3574 //This code needs to be revisited. There is sme_removeKey API, we should
3575 //plan to use that. After the change to use correct index in setkey,
3576 //it is observed that this is invalidating peer
3577 //key index whenever re-key is done. This is affecting data link.
3578 //It should be ok to ignore del_key.
3579#if 0
3580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3581 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3582 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3583 tCsrRoamSetKey setKey;
3584 v_U32_t roamId= 0xFF;
3585
3586 ENTER();
3587
3588 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3589 __func__,pAdapter->device_mode);
3590
3591 if (CSR_MAX_NUM_KEY <= key_index)
3592 {
3593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3594 key_index);
3595
3596 return -EINVAL;
3597 }
3598
3599 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3600 setKey.keyId = key_index;
3601
3602 if (mac_addr)
3603 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3604 else
3605 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3606
3607 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3608
3609 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 )
3612 {
3613
3614 hdd_hostapd_state_t *pHostapdState =
3615 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3616 if( pHostapdState->bssState == BSS_START)
3617 {
3618 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3619
3620 if ( status != eHAL_STATUS_SUCCESS )
3621 {
3622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3623 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3624 __LINE__, status );
3625 }
3626 }
3627 }
3628 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003629 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 )
3631 {
3632 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3633
3634 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3635
3636 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3637 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
3638 __func__, setKey.peerMac[0], setKey.peerMac[1],
3639 setKey.peerMac[2], setKey.peerMac[3],
3640 setKey.peerMac[4], setKey.peerMac[5]);
3641 if(pAdapter->sessionCtx.station.conn_info.connState ==
3642 eConnectionState_Associated)
3643 {
3644 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3645 pAdapter->sessionId, &setKey, &roamId );
3646
3647 if ( 0 != status )
3648 {
3649 hddLog(VOS_TRACE_LEVEL_ERROR,
3650 "%s: sme_RoamSetKey failure, returned %d",
3651 __func__, status);
3652 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3653 return -EINVAL;
3654 }
3655 }
3656 }
3657#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003658 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 return status;
3660}
3661
3662/*
3663 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3664 * This function is used to set the default tx key index
3665 */
3666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3667static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3668 struct net_device *ndev,
3669 u8 key_index,
3670 bool unicast, bool multicast)
3671#else
3672static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3673 struct net_device *ndev,
3674 u8 key_index)
3675#endif
3676{
3677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3678 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3679 int status = 0;
3680 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3681
3682 ENTER();
3683
3684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3685 __func__,pAdapter->device_mode, key_index);
3686
3687 if (CSR_MAX_NUM_KEY <= key_index)
3688 {
3689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
3690 key_index);
3691
3692 return -EINVAL;
3693 }
3694
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003695 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3696 {
3697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3698 "%s:LOGP in Progress. Ignore!!!", __func__);
3699 return -EAGAIN;
3700 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003701
3702 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003703 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 )
3705 {
3706 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3707 (eCSR_ENCRYPT_TYPE_TKIP !=
3708 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3709 (eCSR_ENCRYPT_TYPE_AES !=
3710 pWextState->roamProfile.EncryptionType.encryptionType[0])
3711 )
3712 {
3713 /* if default key index is not same as previous one,
3714 * then update the default key index */
3715
3716 tCsrRoamSetKey setKey;
3717 v_U32_t roamId= 0xFF;
3718 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
3719
3720 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
3721 __func__, key_index);
3722
3723 Keys->defaultIndex = (u8)key_index;
3724 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3725 setKey.keyId = key_index;
3726 setKey.keyLength = Keys->KeyLength[key_index];
3727
3728 vos_mem_copy(&setKey.Key[0],
3729 &Keys->KeyMaterial[key_index][0],
3730 Keys->KeyLength[key_index]);
3731
3732 setKey.keyDirection = eSIR_TX_ONLY;
3733
3734 vos_mem_copy(setKey.peerMac,
3735 &pHddStaCtx->conn_info.bssId[0],
3736 WNI_CFG_BSSID_LEN);
3737
3738 setKey.encType =
3739 pWextState->roamProfile.EncryptionType.encryptionType[0];
3740
3741 /* issue set key request */
3742 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3743 pAdapter->sessionId, &setKey, &roamId );
3744
3745 if ( 0 != status )
3746 {
3747 hddLog(VOS_TRACE_LEVEL_ERROR,
3748 "%s: sme_RoamSetKey failed, returned %d", __func__,
3749 status);
3750 return -EINVAL;
3751 }
3752 }
3753 }
3754
3755 /* In SoftAp mode setting key direction for default mode */
3756 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3757 {
3758 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3759 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3760 (eCSR_ENCRYPT_TYPE_AES !=
3761 pWextState->roamProfile.EncryptionType.encryptionType[0])
3762 )
3763 {
3764 /* Saving key direction for default key index to TX default */
3765 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3766 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3767 }
3768 }
3769
3770 return status;
3771}
3772
Jeff Johnson295189b2012-06-20 16:38:30 -07003773/*
3774 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3775 * This function is used to inform the BSS details to nl80211 interface.
3776 */
3777static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3778 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3779{
3780 struct net_device *dev = pAdapter->dev;
3781 struct wireless_dev *wdev = dev->ieee80211_ptr;
3782 struct wiphy *wiphy = wdev->wiphy;
3783 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3784 int chan_no;
3785 int ie_length;
3786 const char *ie;
3787 unsigned int freq;
3788 struct ieee80211_channel *chan;
3789 int rssi = 0;
3790 struct cfg80211_bss *bss = NULL;
3791
3792 ENTER();
3793
3794 if( NULL == pBssDesc )
3795 {
3796 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3797 return bss;
3798 }
3799
3800 chan_no = pBssDesc->channelId;
3801 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3802 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3803
3804 if( NULL == ie )
3805 {
3806 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3807 return bss;
3808 }
3809
3810#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3811 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3812 {
3813 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3814 }
3815 else
3816 {
3817 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3818 }
3819#else
3820 freq = ieee80211_channel_to_frequency(chan_no);
3821#endif
3822
3823 chan = __ieee80211_get_channel(wiphy, freq);
3824
3825 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3826 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3827 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3828 if (bss == NULL)
3829 {
3830 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3831
3832 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3833 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
3834 pBssDesc->capabilityInfo,
3835 pBssDesc->beaconInterval, ie, ie_length,
3836 rssi, GFP_KERNEL ));
3837}
3838 else
3839 {
3840 return bss;
3841 }
3842}
3843
3844
3845
3846/*
3847 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3848 * This function is used to inform the BSS details to nl80211 interface.
3849 */
3850struct cfg80211_bss*
3851wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3852 tSirBssDescription *bss_desc
3853 )
3854{
3855 /*
3856 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3857 already exists in bss data base of cfg80211 for that particular BSS ID.
3858 Using cfg80211_inform_bss_frame to update the bss entry instead of
3859 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3860 now there is no possibility to get the mgmt(probe response) frame from PE,
3861 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3862 cfg80211_inform_bss_frame.
3863 */
3864 struct net_device *dev = pAdapter->dev;
3865 struct wireless_dev *wdev = dev->ieee80211_ptr;
3866 struct wiphy *wiphy = wdev->wiphy;
3867 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003868#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3869 qcom_ie_age *qie_age = NULL;
3870 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3871#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003872 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003874 const char *ie =
3875 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3876 unsigned int freq;
3877 struct ieee80211_channel *chan;
3878 struct ieee80211_mgmt *mgmt =
3879 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3880 struct cfg80211_bss *bss_status = NULL;
3881 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3882 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003883#ifdef WLAN_OPEN_SOURCE
3884 struct timespec ts;
3885#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003886
3887 ENTER();
3888
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003889 if (!mgmt)
3890 return NULL;
3891
Jeff Johnson295189b2012-06-20 16:38:30 -07003892 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003893
3894#ifdef WLAN_OPEN_SOURCE
3895 /* Android does not want the timestamp from the frame.
3896 Instead it wants a monotonic increasing value */
3897 get_monotonic_boottime(&ts);
3898 mgmt->u.probe_resp.timestamp =
3899 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3900#else
3901 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003902 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3903 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003904
3905#endif
3906
Jeff Johnson295189b2012-06-20 16:38:30 -07003907 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3908 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003909
3910#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3911 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3912 /* Assuming this is the last IE, copy at the end */
3913 ie_length -=sizeof(qcom_ie_age);
3914 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3915 qie_age->element_id = QCOM_VENDOR_IE_ID;
3916 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3917 qie_age->oui_1 = QCOM_OUI1;
3918 qie_age->oui_2 = QCOM_OUI2;
3919 qie_age->oui_3 = QCOM_OUI3;
3920 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3921 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3922#endif
3923
Jeff Johnson295189b2012-06-20 16:38:30 -07003924 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3925
3926 mgmt->frame_control |=
3927 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3928
3929#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3930 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
3931 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3932 {
3933 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3934 }
3935 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
3936 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3937
3938 {
3939 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3940 }
3941 else
3942 {
3943 kfree(mgmt);
3944 return NULL;
3945 }
3946#else
3947 freq = ieee80211_channel_to_frequency(chan_no);
3948#endif
3949 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003950 /*when the band is changed on the fly using the GUI, three things are done
3951 * 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)
3952 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3953 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3954 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3955 * and discards the channels correponding to previous band and calls back with zero bss results.
3956 * 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
3957 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3958 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3959 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3960 * So drop the bss and continue to next bss.
3961 */
3962 if(chan == NULL)
3963 {
3964 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
3965 return NULL;
3966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003967 /*To keep the rssi icon of the connected AP in the scan window
3968 *and the rssi icon of the wireless networks in sync
3969 * */
3970 if (( eConnectionState_Associated ==
3971 pAdapter->sessionCtx.station.conn_info.connState ) &&
3972 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3973 pAdapter->sessionCtx.station.conn_info.bssId,
3974 WNI_CFG_BSSID_LEN)))
3975 {
3976 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3977 rssi = (pAdapter->rssi * 100);
3978 }
3979 else
3980 {
3981 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3982 }
3983
3984 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3985 frame_len, rssi, GFP_KERNEL);
3986 kfree(mgmt);
3987 return bss_status;
3988}
3989
3990/*
3991 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3992 * This function is used to update the BSS data base of CFG8011
3993 */
3994struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
3995 tCsrRoamInfo *pRoamInfo
3996 )
3997{
3998 tCsrRoamConnectedProfile roamProfile;
3999 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4000 struct cfg80211_bss *bss = NULL;
4001
4002 ENTER();
4003
4004 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4005 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4006
4007 if (NULL != roamProfile.pBssDesc)
4008 {
4009 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
4010 &roamProfile);
4011
4012 if (NULL == bss)
4013 {
4014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4015 __func__);
4016 }
4017
4018 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4019 }
4020 else
4021 {
4022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4023 __func__);
4024 }
4025 return bss;
4026}
4027
4028/*
4029 * FUNCTION: wlan_hdd_cfg80211_update_bss
4030 */
4031static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4032 hdd_adapter_t *pAdapter
4033 )
4034{
4035 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4036 tCsrScanResultInfo *pScanResult;
4037 eHalStatus status = 0;
4038 tScanResultHandle pResult;
4039 struct cfg80211_bss *bss_status = NULL;
4040
4041 ENTER();
4042
4043 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4044 {
4045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4046 return -EAGAIN;
4047 }
4048
4049 /*
4050 * start getting scan results and populate cgf80211 BSS database
4051 */
4052 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4053
4054 /* no scan results */
4055 if (NULL == pResult)
4056 {
4057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4058 return status;
4059 }
4060
4061 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4062
4063 while (pScanResult)
4064 {
4065 /*
4066 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4067 * entry already exists in bss data base of cfg80211 for that
4068 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4069 * bss entry instead of cfg80211_inform_bss, But this call expects
4070 * mgmt packet as input. As of now there is no possibility to get
4071 * the mgmt(probe response) frame from PE, converting bss_desc to
4072 * ieee80211_mgmt(probe response) and passing to c
4073 * fg80211_inform_bss_frame.
4074 * */
4075
4076 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4077 &pScanResult->BssDescriptor);
4078
4079
4080 if (NULL == bss_status)
4081 {
4082 hddLog(VOS_TRACE_LEVEL_INFO,
4083 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4084 }
4085 else
4086 {
4087 cfg80211_put_bss(bss_status);
4088 }
4089
4090 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4091 }
4092
4093 sme_ScanResultPurge(hHal, pResult);
4094
4095 return 0;
4096}
4097
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004098void
4099hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4100{
4101 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004102 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4103 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4104 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004105} /****** end hddPrintMacAddr() ******/
4106
4107void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004108hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004109{
4110 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004111 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4112 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4113 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4114 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004115} /****** end hddPrintPmkId() ******/
4116
4117//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4118//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4119
4120//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4121//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4122
4123#define dump_bssid(bssid) \
4124 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004125 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4126 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4127 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004128 }
4129
4130#define dump_pmkid(pMac, pmkid) \
4131 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004132 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4133 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4134 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004135 }
4136
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004137#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004138/*
4139 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4140 * This function is used to notify the supplicant of a new PMKSA candidate.
4141 */
4142int wlan_hdd_cfg80211_pmksa_candidate_notify(
4143 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
4144 int index, bool preauth )
4145{
Jeff Johnsone7245742012-09-05 17:12:55 -07004146#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004147 struct net_device *dev = pAdapter->dev;
4148
4149 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004150 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004151
4152 if( NULL == pRoamInfo )
4153 {
4154 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4155 return -EINVAL;
4156 }
4157
4158 dump_bssid(pRoamInfo->bssid);
4159 cfg80211_pmksa_candidate_notify(dev, index,
4160 pRoamInfo->bssid, preauth, GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07004161#endif /* FEATURE_WLAN_OKC */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004162 return 0;
4163}
4164#endif //FEATURE_WLAN_LFR
4165
Jeff Johnson295189b2012-06-20 16:38:30 -07004166/*
4167 * FUNCTION: hdd_cfg80211_scan_done_callback
4168 * scanning callback function, called after finishing scan
4169 *
4170 */
4171static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
4172 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4173{
4174 struct net_device *dev = (struct net_device *) pContext;
4175 //struct wireless_dev *wdev = dev->ieee80211_ptr;
4176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004177 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4178 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 struct cfg80211_scan_request *req = NULL;
4180 int ret = 0;
4181
4182 ENTER();
4183
4184 hddLog(VOS_TRACE_LEVEL_INFO,
4185 "%s called with halHandle = %p, pContext = %p,"
4186 "scanID = %d, returned status = %d\n",
4187 __func__, halHandle, pContext, (int) scanId, (int) status);
4188
4189 //Block on scan req completion variable. Can't wait forever though.
4190 ret = wait_for_completion_interruptible_timeout(
4191 &pScanInfo->scan_req_completion_event,
4192 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4193 if (!ret)
4194 {
4195 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004196 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004197 }
4198
4199 if(pScanInfo->mScanPending != VOS_TRUE)
4200 {
4201 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004202 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004203 }
4204
4205 /* Check the scanId */
4206 if (pScanInfo->scanId != scanId)
4207 {
4208 hddLog(VOS_TRACE_LEVEL_INFO,
4209 "%s called with mismatched scanId pScanInfo->scanId = %d "
4210 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
4211 (int) scanId);
4212 }
4213
Jeff Johnson295189b2012-06-20 16:38:30 -07004214 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
4215 pAdapter);
4216
4217 if (0 > ret)
4218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
4219
4220
4221 /* If any client wait scan result through WEXT
4222 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004223 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004224 {
4225 /* The other scan request waiting for current scan finish
4226 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004227 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004228 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004229 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 }
4231 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004232 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 {
4234 struct net_device *dev = pAdapter->dev;
4235 union iwreq_data wrqu;
4236 int we_event;
4237 char *msg;
4238
4239 memset(&wrqu, '\0', sizeof(wrqu));
4240 we_event = SIOCGIWSCAN;
4241 msg = NULL;
4242 wireless_send_event(dev, we_event, &wrqu, msg);
4243 }
4244 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004245 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004246
4247 /* Get the Scan Req */
4248 req = pAdapter->request;
4249
4250 if (!req)
4251 {
4252 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004253 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004254 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004255 }
4256
4257 /*
4258 * setting up 0, just in case.
4259 */
4260 req->n_ssids = 0;
4261 req->n_channels = 0;
4262 req->ie = 0;
4263
Jeff Johnson295189b2012-06-20 16:38:30 -07004264 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004265 /* Scan is no longer pending */
4266 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004267
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004268 /*
4269 * cfg80211_scan_done informing NL80211 about completion
4270 * of scanning
4271 */
4272 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004273 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004274
Jeff Johnsone7245742012-09-05 17:12:55 -07004275allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004276 /* release the wake lock at the end of the scan*/
4277 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004278
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004279 /* Acquire wakelock to handle the case where APP's tries to suspend
4280 * immediatly after the driver gets connect request(i.e after scan)
4281 * from supplicant, this result in app's is suspending and not able
4282 * to process the connect request to AP */
4283 hdd_allow_suspend_timeout(100);
4284
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004285#ifdef FEATURE_WLAN_TDLS
4286 wlan_hdd_tdls_scan_done_callback(pAdapter);
4287#endif
4288
Jeff Johnson295189b2012-06-20 16:38:30 -07004289 EXIT();
4290 return 0;
4291}
4292
4293/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004294 * FUNCTION: hdd_isScanAllowed
4295 * Go through each adapter and check if scan allowed
4296 *
4297 */
4298v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4299{
4300 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4301 hdd_station_ctx_t *pHddStaCtx = NULL;
4302 hdd_adapter_t *pAdapter = NULL;
4303 VOS_STATUS status = 0;
4304 v_U8_t staId = 0;
4305 v_U8_t *staMac = NULL;
4306
4307 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4308
4309 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4310 {
4311 pAdapter = pAdapterNode->pAdapter;
4312
4313 if( pAdapter )
4314 {
4315 hddLog(VOS_TRACE_LEVEL_INFO,
4316 "%s: Adapter with device mode %d exists",
4317 __func__, pAdapter->device_mode);
4318 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4319 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4320 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4321 {
4322 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4323 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4324 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4325 {
4326 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4327 hddLog(VOS_TRACE_LEVEL_ERROR,
4328 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
4329 "middle of WPS/EAPOL exchange.", __func__,
4330 staMac[0], staMac[1], staMac[2],
4331 staMac[3], staMac[4], staMac[5]);
4332 return VOS_FALSE;
4333 }
4334 }
4335 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4336 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4337 {
4338 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4339 {
4340 if ((pAdapter->aStaInfo[staId].isUsed) &&
4341 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4342 {
4343 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4344
4345 hddLog(VOS_TRACE_LEVEL_ERROR,
4346 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
4347 "middle of WPS/EAPOL exchange.", __func__,
4348 staMac[0], staMac[1], staMac[2],
4349 staMac[3], staMac[4], staMac[5]);
4350 return VOS_FALSE;
4351 }
4352 }
4353 }
4354 }
4355 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4356 pAdapterNode = pNext;
4357 }
4358 hddLog(VOS_TRACE_LEVEL_INFO,
4359 "%s: Scan allowed", __func__);
4360 return VOS_TRUE;
4361}
4362
4363/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004364 * FUNCTION: wlan_hdd_cfg80211_scan
4365 * this scan respond to scan trigger and update cfg80211 scan database
4366 * later, scan dump command can be used to recieve scan results
4367 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004368int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4369#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4370 struct net_device *dev,
4371#endif
4372 struct cfg80211_scan_request *request)
4373{
4374#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4375 struct net_device *dev = request->wdev->netdev;
4376#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
4378 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4379 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4380 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4381 tCsrScanRequest scanRequest;
4382 tANI_U8 *channelList = NULL, i;
4383 v_U32_t scanId = 0;
4384 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004385 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004386 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004387
4388 ENTER();
4389
4390 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4391 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004392
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004393 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004394 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004395 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004396 {
4397 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004398 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4399 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004400 return -EBUSY;
4401 }
4402
Jeff Johnson295189b2012-06-20 16:38:30 -07004403#ifdef WLAN_BTAMP_FEATURE
4404 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004405 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004406 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004407 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004408 "%s: No scanning when AMP is on", __func__);
4409 return -EOPNOTSUPP;
4410 }
4411#endif
4412 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004413 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004414 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004415 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004416 "%s: Not scanning on device_mode = %d",
4417 __func__, pAdapter->device_mode);
4418 return -EOPNOTSUPP;
4419 }
4420
4421 if (TRUE == pScanInfo->mScanPending)
4422 {
4423 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004424 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004425 }
4426
4427 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4428 {
4429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4430 "%s:LOGP in Progress. Ignore!!!", __func__);
4431 return -EAGAIN;
4432 }
4433
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004434 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4435 {
4436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4437 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4438 return -EAGAIN;
4439 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004440 //Don't Allow Scan and return busy if Remain On
4441 //Channel and action frame is pending
4442 //Otherwise Cancel Remain On Channel and allow Scan
4443 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004444 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004445 {
4446 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4447 return -EBUSY;
4448 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004449#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004450 /* if tdls disagree scan right now, return immediately.
4451 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4452 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4453 */
4454 status = wlan_hdd_tdls_scan_callback (pAdapter,
4455 wiphy,
4456#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4457 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004458#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004459 request);
4460 if(status <= 0)
4461 {
4462 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4463 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004464 }
4465#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004466
Jeff Johnson295189b2012-06-20 16:38:30 -07004467 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4468 {
4469 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004470 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004471 return -EAGAIN;
4472 }
4473 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4474 {
4475 hddLog(VOS_TRACE_LEVEL_WARN,
4476 "%s: MAX TM Level Scan not allowed", __func__);
4477 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4478 return -EBUSY;
4479 }
4480 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4481
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004482 /* Check if scan is allowed at this point of time.
4483 */
4484 if (!hdd_isScanAllowed(pHddCtx))
4485 {
4486 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4487 return -EBUSY;
4488 }
4489
Jeff Johnson295189b2012-06-20 16:38:30 -07004490 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4491
4492 if (NULL != request)
4493 {
4494 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
4495 (int)request->n_ssids);
4496
4497 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4498 * Becasue of this, driver is assuming that this is not wildcard scan and so
4499 * is not aging out the scan results.
4500 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004501 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004502 {
4503 request->n_ssids = 0;
4504 }
4505
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004506 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004507 {
4508 tCsrSSIDInfo *SsidInfo;
4509 int j;
4510 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4511 /* Allocate num_ssid tCsrSSIDInfo structure */
4512 SsidInfo = scanRequest.SSIDs.SSIDList =
4513 ( tCsrSSIDInfo *)vos_mem_malloc(
4514 request->n_ssids*sizeof(tCsrSSIDInfo));
4515
4516 if(NULL == scanRequest.SSIDs.SSIDList)
4517 {
4518 hddLog(VOS_TRACE_LEVEL_ERROR,
4519 "memory alloc failed SSIDInfo buffer");
4520 return -ENOMEM;
4521 }
4522
4523 /* copy all the ssid's and their length */
4524 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4525 {
4526 /* get the ssid length */
4527 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4528 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4529 SsidInfo->SSID.length);
4530 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4531 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4532 j, SsidInfo->SSID.ssId);
4533 }
4534 /* set the scan type to active */
4535 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4536 }
4537 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4538 {
4539 /* set the scan type to active */
4540 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4541 }
4542 else
4543 {
4544 /*Set the scan type to default type, in this case it is ACTIVE*/
4545 scanRequest.scanType = pScanInfo->scan_mode;
4546 }
4547 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
4548 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4549 }
4550 else
4551 {
4552 /* set the scan type to active */
4553 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4554 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4555
4556 /* set min and max channel time to zero */
4557 scanRequest.minChnTime = 0;
4558 scanRequest.maxChnTime = 0;
4559 }
4560
4561 /* set BSSType to default type */
4562 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4563
4564 /*TODO: scan the requested channels only*/
4565
4566 /*Right now scanning all the channels */
4567 if( request )
4568 {
4569 if( request->n_channels )
4570 {
4571 channelList = vos_mem_malloc( request->n_channels );
4572 if( NULL == channelList )
4573 {
4574 status = -ENOMEM;
4575 goto free_mem;
4576 }
4577
4578 for( i = 0 ; i < request->n_channels ; i++ )
4579 channelList[i] = request->channels[i]->hw_value;
4580 }
4581
4582 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4583 scanRequest.ChannelInfo.ChannelList = channelList;
4584
4585 /* set requestType to full scan */
4586 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004587
4588 /* Flush the scan results(only p2p beacons) for STA scan and P2P
4589 * search (Flush on both full scan and social scan but not on single
4590 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
4591 */
4592
4593 /* Supplicant does single channel scan after 8-way handshake
4594 * and in that case driver shoudnt flush scan results. If
4595 * driver flushes the scan results here and unfortunately if
4596 * the AP doesnt respond to our probe req then association
4597 * fails which is not desired
4598 */
4599
4600 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4601 {
4602 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4603 pAdapter->sessionId );
4604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004605
4606 if( request->ie_len )
4607 {
4608 /* save this for future association (join requires this) */
4609 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4610 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4611 pScanInfo->scanAddIE.length = request->ie_len;
4612
4613 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004614 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4615 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004616 )
4617 {
4618 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4619 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4620 }
4621
4622 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4623 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4624
Jeff Johnson295189b2012-06-20 16:38:30 -07004625 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4626 request->ie_len);
4627 if (pP2pIe != NULL)
4628 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004629#ifdef WLAN_FEATURE_P2P_DEBUG
4630 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4631 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4632 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4633 {
4634 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4635 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4636 "Go nego completed to Connection is started");
4637 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4638 "for 8way Handshake");
4639 }
4640 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4641 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4642 {
4643 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4644 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4645 "Disconnected state to Connection is started");
4646 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4647 "for 4way Handshake");
4648 }
4649#endif
4650
Jeff Johnsone7245742012-09-05 17:12:55 -07004651 /* no_cck will be set during p2p find to disable 11b rates */
4652 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004653 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 hddLog(VOS_TRACE_LEVEL_INFO,
4655 "%s: This is a P2P Search", __func__);
4656 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004657
Jeff Johnsone7245742012-09-05 17:12:55 -07004658 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4659 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004660 /* set requestType to P2P Discovery */
4661 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004662 }
4663
4664 /*
4665 Skip Dfs Channel in case of P2P Search
4666 if it is set in ini file
4667 */
4668 if(cfg_param->skipDfsChnlInP2pSearch)
4669 {
4670 scanRequest.skipDfsChnlInP2pSearch = 1;
4671 }
4672 else
4673 {
4674 scanRequest.skipDfsChnlInP2pSearch = 0;
4675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004676
Jeff Johnson295189b2012-06-20 16:38:30 -07004677 }
4678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 }
4680 }
4681
4682 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4683
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004684 /* acquire the wakelock to avoid the apps suspend during the scan. To
4685 * address the following issues.
4686 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4687 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4688 * for long time, this result in apps running at full power for long time.
4689 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4690 * be stuck in full power because of resume BMPS
4691 */
4692 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004693
4694 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 pAdapter->sessionId, &scanRequest, &scanId,
4696 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004697
Jeff Johnson295189b2012-06-20 16:38:30 -07004698 if (eHAL_STATUS_SUCCESS != status)
4699 {
4700 hddLog(VOS_TRACE_LEVEL_ERROR,
4701 "%s: sme_ScanRequest returned error %d", __func__, status);
4702 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004703 if(eHAL_STATUS_RESOURCES == status)
4704 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004705 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 -07004706 status = -EBUSY;
4707 } else {
4708 status = -EIO;
4709 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004710 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004711 goto free_mem;
4712 }
4713
4714 pScanInfo->mScanPending = TRUE;
4715 pAdapter->request = request;
4716 pScanInfo->scanId = scanId;
4717
4718 complete(&pScanInfo->scan_req_completion_event);
4719
4720free_mem:
4721 if( scanRequest.SSIDs.SSIDList )
4722 {
4723 vos_mem_free(scanRequest.SSIDs.SSIDList);
4724 }
4725
4726 if( channelList )
4727 vos_mem_free( channelList );
4728
4729 EXIT();
4730
4731 return status;
4732}
4733
4734/*
4735 * FUNCTION: wlan_hdd_cfg80211_connect_start
4736 * This function is used to start the association process
4737 */
4738int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004739 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004740{
4741 int status = 0;
4742 hdd_wext_state_t *pWextState;
4743 v_U32_t roamId;
4744 tCsrRoamProfile *pRoamProfile;
4745 eMib_dot11DesiredBssType connectedBssType;
4746 eCsrAuthType RSNAuthType;
4747
4748 ENTER();
4749
4750 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4751
4752 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4753 {
4754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4755 return -EINVAL;
4756 }
4757
4758 pRoamProfile = &pWextState->roamProfile;
4759
4760 if (pRoamProfile)
4761 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004762 int ret = 0;
4763 hdd_station_ctx_t *pHddStaCtx;
4764 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4765 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4766
4767 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4768 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4769 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 {
4771 /* Issue disconnect to CSR */
4772 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4773 if( eHAL_STATUS_SUCCESS ==
4774 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4775 pAdapter->sessionId,
4776 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4777 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004778 ret = wait_for_completion_interruptible_timeout(
4779 &pAdapter->disconnect_comp_var,
4780 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4781 if (0 == ret)
4782 {
4783 VOS_ASSERT(0);
4784 }
4785 }
4786 }
4787 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4788 {
4789 ret = wait_for_completion_interruptible_timeout(
4790 &pAdapter->disconnect_comp_var,
4791 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4792 if (0 == ret)
4793 {
4794 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004795 }
4796 }
4797
4798 if (HDD_WMM_USER_MODE_NO_QOS ==
4799 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4800 {
4801 /*QoS not enabled in cfg file*/
4802 pRoamProfile->uapsd_mask = 0;
4803 }
4804 else
4805 {
4806 /*QoS enabled, update uapsd mask from cfg file*/
4807 pRoamProfile->uapsd_mask =
4808 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4809 }
4810
4811 pRoamProfile->SSIDs.numOfSSIDs = 1;
4812 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4813 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
4814 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
4815 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4816 ssid, ssid_len);
4817
4818 if (bssid)
4819 {
4820 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4821 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4822 WNI_CFG_BSSID_LEN);
4823 /* Save BSSID in seperate variable as well, as RoamProfile
4824 BSSID is getting zeroed out in the association process. And in
4825 case of join failure we should send valid BSSID to supplicant
4826 */
4827 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4828 WNI_CFG_BSSID_LEN);
4829 }
4830
4831 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4832 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
4833 {
4834 /*set gen ie*/
4835 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4836 /*set auth*/
4837 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4838 }
4839 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
4840 eCSR_AUTH_TYPE_OPEN_SYSTEM)
4841 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4842 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4843 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4844 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4845 )
4846 {
4847 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4848 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4849 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
4850 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
4851 eCSR_AUTH_TYPE_AUTOSWITCH;
4852 pWextState->roamProfile.AuthType.authType[0] =
4853 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4854 }
4855#ifdef FEATURE_WLAN_WAPI
4856 if (pAdapter->wapi_info.nWapiMode)
4857 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004858 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 switch (pAdapter->wapi_info.wapiAuthMode)
4860 {
4861 case WAPI_AUTH_MODE_PSK:
4862 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004863 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 pAdapter->wapi_info.wapiAuthMode);
4865 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4866 break;
4867 }
4868 case WAPI_AUTH_MODE_CERT:
4869 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004870 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 pAdapter->wapi_info.wapiAuthMode);
4872 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4873 break;
4874 }
4875 } // End of switch
4876 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4877 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4878 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004879 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004880 pRoamProfile->AuthType.numEntries = 1;
4881 pRoamProfile->EncryptionType.numEntries = 1;
4882 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4883 pRoamProfile->mcEncryptionType.numEntries = 1;
4884 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4885 }
4886 }
4887#endif /* FEATURE_WLAN_WAPI */
4888 pRoamProfile->csrPersona = pAdapter->device_mode;
4889
Jeff Johnson32d95a32012-09-10 13:15:23 -07004890 if( operatingChannel )
4891 {
4892 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4893 pRoamProfile->ChannelInfo.numOfChannels = 1;
4894 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004895 else
4896 {
4897 pRoamProfile->ChannelInfo.ChannelList = NULL;
4898 pRoamProfile->ChannelInfo.numOfChannels = 0;
4899 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004900
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004901 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4902 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
4903 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
4904 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004905 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4906 */
4907 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4908 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4909 eConnectionState_Connecting);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004910
Jeff Johnson295189b2012-06-20 16:38:30 -07004911 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4912 pAdapter->sessionId, pRoamProfile, &roamId);
4913
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004914 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304915 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4916
4917 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4919 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4920 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304921 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004922 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304923 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004924
4925 pRoamProfile->ChannelInfo.ChannelList = NULL;
4926 pRoamProfile->ChannelInfo.numOfChannels = 0;
4927
Jeff Johnson295189b2012-06-20 16:38:30 -07004928 }
4929 else
4930 {
4931 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4932 return -EINVAL;
4933 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004934 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 return status;
4936}
4937
4938/*
4939 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4940 * This function is used to set the authentication type (OPEN/SHARED).
4941 *
4942 */
4943static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4944 enum nl80211_auth_type auth_type)
4945{
4946 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4947 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4948
4949 ENTER();
4950
4951 /*set authentication type*/
4952 switch (auth_type)
4953 {
4954 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4955 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004956#ifdef WLAN_FEATURE_VOWIFI_11R
4957 case NL80211_AUTHTYPE_FT:
4958#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 hddLog(VOS_TRACE_LEVEL_INFO,
4960 "%s: set authentication type to OPEN", __func__);
4961 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4962 break;
4963
4964 case NL80211_AUTHTYPE_SHARED_KEY:
4965 hddLog(VOS_TRACE_LEVEL_INFO,
4966 "%s: set authentication type to SHARED", __func__);
4967 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4968 break;
4969#ifdef FEATURE_WLAN_CCX
4970 case NL80211_AUTHTYPE_NETWORK_EAP:
4971 hddLog(VOS_TRACE_LEVEL_INFO,
4972 "%s: set authentication type to CCKM WPA", __func__);
4973 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4974 break;
4975#endif
4976
4977
4978 default:
4979 hddLog(VOS_TRACE_LEVEL_ERROR,
4980 "%s: Unsupported authentication type %d", __func__,
4981 auth_type);
4982 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4983 return -EINVAL;
4984 }
4985
4986 pWextState->roamProfile.AuthType.authType[0] =
4987 pHddStaCtx->conn_info.authType;
4988 return 0;
4989}
4990
4991/*
4992 * FUNCTION: wlan_hdd_set_akm_suite
4993 * This function is used to set the key mgmt type(PSK/8021x).
4994 *
4995 */
4996static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
4997 u32 key_mgmt
4998 )
4999{
5000 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5001 ENTER();
5002
5003 /*set key mgmt type*/
5004 switch(key_mgmt)
5005 {
5006 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305007#ifdef WLAN_FEATURE_VOWIFI_11R
5008 case WLAN_AKM_SUITE_FT_PSK:
5009#endif
5010 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 __func__);
5012 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5013 break;
5014
5015 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305016#ifdef WLAN_FEATURE_VOWIFI_11R
5017 case WLAN_AKM_SUITE_FT_8021X:
5018#endif
5019 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 __func__);
5021 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5022 break;
5023#ifdef FEATURE_WLAN_CCX
5024#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5025#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5026 case WLAN_AKM_SUITE_CCKM:
5027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5028 __func__);
5029 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5030 break;
5031#endif
5032
5033 default:
5034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
5035 __func__, key_mgmt);
5036 return -EINVAL;
5037
5038 }
5039 return 0;
5040}
5041
5042/*
5043 * FUNCTION: wlan_hdd_cfg80211_set_cipher
5044 * This function is used to set the encryption type
5045 * (NONE/WEP40/WEP104/TKIP/CCMP).
5046 */
5047static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5048 u32 cipher,
5049 bool ucast
5050 )
5051{
5052 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5053 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5054 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5055
5056 ENTER();
5057
5058 if (!cipher)
5059 {
5060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
5061 __func__, cipher);
5062 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5063 }
5064 else
5065 {
5066
5067 /*set encryption method*/
5068 switch (cipher)
5069 {
5070 case IW_AUTH_CIPHER_NONE:
5071 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5072 break;
5073
5074 case WLAN_CIPHER_SUITE_WEP40:
5075 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
5076 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5077 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
5078 else
5079 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5080 break;
5081
5082 case WLAN_CIPHER_SUITE_WEP104:
5083 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
5084 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5085 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
5086 else
5087 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5088 break;
5089
5090 case WLAN_CIPHER_SUITE_TKIP:
5091 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5092 break;
5093
5094 case WLAN_CIPHER_SUITE_CCMP:
5095 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5096 break;
5097#ifdef FEATURE_WLAN_WAPI
5098 case WLAN_CIPHER_SUITE_SMS4:
5099 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5100 break;
5101#endif
5102
5103#ifdef FEATURE_WLAN_CCX
5104 case WLAN_CIPHER_SUITE_KRK:
5105 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5106 break;
5107#endif
5108 default:
5109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
5110 __func__, cipher);
5111 return -EOPNOTSUPP;
5112 }
5113 }
5114
5115 if (ucast)
5116 {
5117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
5118 __func__, encryptionType);
5119 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5120 pWextState->roamProfile.EncryptionType.numEntries = 1;
5121 pWextState->roamProfile.EncryptionType.encryptionType[0] =
5122 encryptionType;
5123 }
5124 else
5125 {
5126 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
5127 __func__, encryptionType);
5128 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5129 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5130 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5131 }
5132
5133 return 0;
5134}
5135
5136
5137/*
5138 * FUNCTION: wlan_hdd_cfg80211_set_ie
5139 * This function is used to parse WPA/RSN IE's.
5140 */
5141int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5142 u8 *ie,
5143 size_t ie_len
5144 )
5145{
5146 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5147 u8 *genie = ie;
5148 v_U16_t remLen = ie_len;
5149#ifdef FEATURE_WLAN_WAPI
5150 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5151 u16 *tmp;
5152 v_U16_t akmsuiteCount;
5153 int *akmlist;
5154#endif
5155 ENTER();
5156
5157 /* clear previous assocAddIE */
5158 pWextState->assocAddIE.length = 0;
5159 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5160
5161 while (remLen >= 2)
5162 {
5163 v_U16_t eLen = 0;
5164 v_U8_t elementId;
5165 elementId = *genie++;
5166 eLen = *genie++;
5167 remLen -= 2;
5168
5169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
5170 __func__, elementId, eLen);
5171
5172 switch ( elementId )
5173 {
5174 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005175 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 -07005176 {
5177 hddLog(VOS_TRACE_LEVEL_ERROR,
5178 "%s: Invalid WPA IE", __func__);
5179 return -EINVAL;
5180 }
5181 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
5182 {
5183 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5184 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
5185 __func__, eLen + 2);
5186
5187 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5188 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005189 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5190 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005191 VOS_ASSERT(0);
5192 return -ENOMEM;
5193 }
5194 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5195 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5196 pWextState->assocAddIE.length += eLen + 2;
5197
5198 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5199 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5200 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5201 }
5202 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5203 {
5204 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5205 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5206 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5207 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5208 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5209 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5211 P2P_OUI_TYPE_SIZE))
5212 /*Consider P2P IE, only for P2P Client */
5213 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5214 {
5215 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5216 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
5217 __func__, eLen + 2);
5218
5219 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5220 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005221 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5222 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005223 VOS_ASSERT(0);
5224 return -ENOMEM;
5225 }
5226 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5227 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5228 pWextState->assocAddIE.length += eLen + 2;
5229
5230 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5231 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005233#ifdef WLAN_FEATURE_WFD
5234 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5235 WFD_OUI_TYPE_SIZE))
5236 /*Consider WFD IE, only for P2P Client */
5237 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5238 {
5239 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5240 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
5241 __func__, eLen + 2);
5242
5243 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5244 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005245 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5246 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 VOS_ASSERT(0);
5248 return -ENOMEM;
5249 }
5250 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5251 // WPS IE + P2P IE + WFD IE
5252 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5253 pWextState->assocAddIE.length += eLen + 2;
5254
5255 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5256 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5257 }
5258#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005259 /* Appending HS 2.0 Indication Element in Assiciation Request */
5260 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005261 HS20_OUI_TYPE_SIZE)) )
5262 {
5263 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5264 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
5265 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005266
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005267 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5268 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005269 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5270 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005271 VOS_ASSERT(0);
5272 return -ENOMEM;
5273 }
5274 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5275 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005276
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005277 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5278 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5279 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005280
Jeff Johnson295189b2012-06-20 16:38:30 -07005281 break;
5282 case DOT11F_EID_RSN:
5283 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5284 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5285 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5286 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5287 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5288 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005289 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5290 case DOT11F_EID_EXTCAP:
5291 {
5292 v_U16_t curAddIELen = pWextState->assocAddIE.length;
5293 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
5294 __func__, eLen + 2);
5295
5296 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5297 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005298 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5299 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005300 VOS_ASSERT(0);
5301 return -ENOMEM;
5302 }
5303 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5304 pWextState->assocAddIE.length += eLen + 2;
5305
5306 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5307 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5308 break;
5309 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005310#ifdef FEATURE_WLAN_WAPI
5311 case WLAN_EID_WAPI:
5312 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5313 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5314 pAdapter->wapi_info.nWapiMode);
5315 tmp = (u16 *)ie;
5316 tmp = tmp + 2; // Skip element Id and Len, Version
5317 akmsuiteCount = WPA_GET_LE16(tmp);
5318 tmp = tmp + 1;
5319 akmlist = (int *)(tmp);
5320 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5321 {
5322 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5323 }
5324 else
5325 {
5326 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5327 VOS_ASSERT(0);
5328 return -EINVAL;
5329 }
5330
5331 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5332 {
5333 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005334 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
5336 }
5337 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
5338 {
5339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005340 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005341 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5342 }
5343 break;
5344#endif
5345 default:
5346 hddLog (VOS_TRACE_LEVEL_ERROR,
5347 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005348 /* when Unknown IE is received we should break and continue
5349 * to the next IE in the buffer instead we were returning
5350 * so changing this to break */
5351 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 }
5353 genie += eLen;
5354 remLen -= eLen;
5355 }
5356 EXIT();
5357 return 0;
5358}
5359
5360/*
5361 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5362 * This function is used to initialize the security
5363 * parameters during connect operation.
5364 */
5365int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
5366 struct cfg80211_connect_params *req
5367 )
5368{
5369 int status = 0;
5370 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5371 ENTER();
5372
5373 /*set wpa version*/
5374 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5375
5376 if (req->crypto.wpa_versions)
5377 {
5378 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
5379 && ( (req->ie_len)
5380 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
5381 // Make sure that it is including a WPA IE.
5382 /* Currently NL is putting WPA version 1 even for open,
5383 * since p2p ie is also put in same buffer.
5384 * */
5385 {
5386 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5387 }
5388 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5389 {
5390 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5391 }
5392 }
5393
5394 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
5395 pWextState->wpaVersion);
5396
5397 /*set authentication type*/
5398 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5399
5400 if (0 > status)
5401 {
5402 hddLog(VOS_TRACE_LEVEL_ERROR,
5403 "%s: failed to set authentication type ", __func__);
5404 return status;
5405 }
5406
5407 /*set key mgmt type*/
5408 if (req->crypto.n_akm_suites)
5409 {
5410 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5411 if (0 > status)
5412 {
5413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
5414 __func__);
5415 return status;
5416 }
5417 }
5418
5419 /*set pairwise cipher type*/
5420 if (req->crypto.n_ciphers_pairwise)
5421 {
5422 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5423 req->crypto.ciphers_pairwise[0], true);
5424 if (0 > status)
5425 {
5426 hddLog(VOS_TRACE_LEVEL_ERROR,
5427 "%s: failed to set unicast cipher type", __func__);
5428 return status;
5429 }
5430 }
5431 else
5432 {
5433 /*Reset previous cipher suite to none*/
5434 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5435 if (0 > status)
5436 {
5437 hddLog(VOS_TRACE_LEVEL_ERROR,
5438 "%s: failed to set unicast cipher type", __func__);
5439 return status;
5440 }
5441 }
5442
5443 /*set group cipher type*/
5444 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5445 false);
5446
5447 if (0 > status)
5448 {
5449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
5450 __func__);
5451 return status;
5452 }
5453
Chet Lanctot186b5732013-03-18 10:26:30 -07005454#ifdef WLAN_FEATURE_11W
5455 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5456#endif
5457
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5459 if (req->ie_len)
5460 {
5461 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5462 if ( 0 > status)
5463 {
5464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
5465 __func__);
5466 return status;
5467 }
5468 }
5469
5470 /*incase of WEP set default key information*/
5471 if (req->key && req->key_len)
5472 {
5473 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5474 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5475 )
5476 {
5477 if ( IW_AUTH_KEY_MGMT_802_1X
5478 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5479 {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
5481 __func__);
5482 return -EOPNOTSUPP;
5483 }
5484 else
5485 {
5486 u8 key_len = req->key_len;
5487 u8 key_idx = req->key_idx;
5488
5489 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
5490 && (CSR_MAX_NUM_KEY > key_idx)
5491 )
5492 {
5493 hddLog(VOS_TRACE_LEVEL_INFO,
5494 "%s: setting default wep key, key_idx = %hu key_len %hu",
5495 __func__, key_idx, key_len);
5496 vos_mem_copy(
5497 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
5498 req->key, key_len);
5499 pWextState->roamProfile.Keys.KeyLength[key_idx] =
5500 (u8)key_len;
5501 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5502 }
5503 }
5504 }
5505 }
5506
5507 return status;
5508}
5509
5510/*
5511 * FUNCTION: wlan_hdd_cfg80211_set_privacy
5512 * This function is used to initialize the security
5513 * parameters during connect operation.
5514 */
5515static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
5516 struct net_device *ndev,
5517 struct cfg80211_connect_params *req
5518 )
5519{
5520 int status = 0;
5521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
5522 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5523 hdd_context_t *pHddCtx = NULL;
5524
5525 ENTER();
5526
5527 hddLog(VOS_TRACE_LEVEL_INFO,
5528 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5529
5530 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5531 {
5532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5533 "%s:LOGP in Progress. Ignore!!!", __func__);
5534 return -EAGAIN;
5535 }
5536
5537#ifdef WLAN_BTAMP_FEATURE
5538 //Infra connect not supported when AMP traffic is on.
5539 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
5540 {
5541 hddLog(VOS_TRACE_LEVEL_ERROR,
5542 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005543 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 }
5545#endif
5546 /*initialise security parameters*/
5547 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
5548
5549 if ( 0 > status)
5550 {
5551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
5552 __func__);
5553 return status;
5554 }
5555
5556 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005557 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5559 (vos_concurrent_sessions_running()))
5560 {
5561 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5562
5563 if (NULL != pVosContext)
5564 {
5565 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5566 if(NULL != pHddCtx)
5567 {
5568 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5569 }
5570 }
5571 }
5572
Mohit Khanna765234a2012-09-11 15:08:35 -07005573 if ( req->channel )
5574 {
5575 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5576 req->ssid_len, req->bssid,
5577 req->channel->hw_value);
5578 }
5579 else
5580 {
5581 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5582 req->ssid_len, req->bssid,
5583 0);
5584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005585
5586 if (0 > status)
5587 {
5588 //ReEnable BMPS if disabled
5589 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5590 (NULL != pHddCtx))
5591 {
5592 //ReEnable Bmps and Imps back
5593 hdd_enable_bmps_imps(pHddCtx);
5594 }
5595
5596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5597 return status;
5598 }
5599 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5600 EXIT();
5601 return status;
5602}
5603
5604
5605/*
5606 * FUNCTION: wlan_hdd_cfg80211_disconnect
5607 * This function is used to issue a disconnect request to SME
5608 */
5609static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
5610 struct net_device *dev,
5611 u16 reason
5612 )
5613{
5614 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5615 tCsrRoamProfile *pRoamProfile =
5616 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5617 int status = 0;
5618 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005619#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005620 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005621 tANI_U8 staIdx;
5622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005623
5624 ENTER();
5625
5626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
5627 __func__,pAdapter->device_mode);
5628
5629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5630 __func__, reason);
5631
5632 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5633 {
5634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5635 "%s:LOGP in Progress. Ignore!!!",__func__);
5636 return -EAGAIN;
5637 }
5638 if (NULL != pRoamProfile)
5639 {
5640 /*issue disconnect request to SME, if station is in connected state*/
5641 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5642 {
5643 eCsrRoamDisconnectReason reasonCode =
5644 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5645 switch(reason)
5646 {
5647 case WLAN_REASON_MIC_FAILURE:
5648 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5649 break;
5650
5651 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5652 case WLAN_REASON_DISASSOC_AP_BUSY:
5653 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5654 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5655 break;
5656
5657 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5658 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5659 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5660 break;
5661
5662 case WLAN_REASON_DEAUTH_LEAVING:
5663 default:
5664 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5665 break;
5666 }
5667 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5668 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5669 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5670
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005671#ifdef FEATURE_WLAN_TDLS
5672 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005673 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005674 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005675 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5676 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005677 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005678 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005679 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005680 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005681 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005682 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005683 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005684 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005685 pAdapter->sessionId,
5686 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005687 }
5688 }
5689#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 /*issue disconnect*/
5691 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5692 pAdapter->sessionId, reasonCode);
5693
5694 if ( 0 != status)
5695 {
5696 hddLog(VOS_TRACE_LEVEL_ERROR,
5697 "%s csrRoamDisconnect failure, returned %d \n",
5698 __func__, (int)status );
5699 return -EINVAL;
5700 }
5701
5702 wait_for_completion_interruptible_timeout(
5703 &pAdapter->disconnect_comp_var,
5704 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5705
5706
5707 /*stop tx queues*/
5708 netif_tx_disable(dev);
5709 netif_carrier_off(dev);
5710 }
5711 }
5712 else
5713 {
5714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5715 }
5716
5717 return status;
5718}
5719
5720/*
5721 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
5722 * This function is used to initialize the security
5723 * settings in IBSS mode.
5724 */
5725static int wlan_hdd_cfg80211_set_privacy_ibss(
5726 hdd_adapter_t *pAdapter,
5727 struct cfg80211_ibss_params *params
5728 )
5729{
5730 int status = 0;
5731 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5732 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5733 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5734
5735 ENTER();
5736
5737 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5738
5739 if (params->ie_len && ( NULL != params->ie) )
5740 {
5741 if (WLAN_EID_RSN == params->ie[0])
5742 {
5743 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5744 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5745 }
5746 else
5747 {
5748 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5749 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5750 }
5751 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5752
5753 if (0 > status)
5754 {
5755 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
5756 __func__);
5757 return status;
5758 }
5759 }
5760
5761 pWextState->roamProfile.AuthType.authType[0] =
5762 pHddStaCtx->conn_info.authType =
5763 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5764
5765 if (params->privacy)
5766 {
5767 /* Security enabled IBSS, At this time there is no information available
5768 * about the security paramters, so initialise the encryption type to
5769 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
5770 * The correct security parameters will be updated later in
5771 * wlan_hdd_cfg80211_add_key */
5772 /* Hal expects encryption type to be set inorder
5773 *enable privacy bit in beacons */
5774
5775 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5776 }
5777
5778 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5779 pWextState->roamProfile.EncryptionType.numEntries = 1;
5780 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5781
5782 return status;
5783}
5784
5785/*
5786 * FUNCTION: wlan_hdd_cfg80211_join_ibss
5787 * This function is used to create/join an IBSS
5788 */
5789static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
5790 struct net_device *dev,
5791 struct cfg80211_ibss_params *params
5792 )
5793{
5794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5795 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5796 tCsrRoamProfile *pRoamProfile;
5797 int status;
5798 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5799
5800 ENTER();
5801
5802 hddLog(VOS_TRACE_LEVEL_INFO,
5803 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5804
5805 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5806 {
5807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5808 "%s:LOGP in Progress. Ignore!!!", __func__);
5809 return -EAGAIN;
5810 }
5811
5812 if (NULL == pWextState)
5813 {
5814 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5815 __func__);
5816 return -EIO;
5817 }
5818
5819 pRoamProfile = &pWextState->roamProfile;
5820
5821 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5822 {
5823 hddLog (VOS_TRACE_LEVEL_ERROR,
5824 "%s Interface type is not set to IBSS \n", __func__);
5825 return -EINVAL;
5826 }
5827
5828 /* Set Channel */
5829 if (NULL != params->channel)
5830 {
5831 u8 channelNum;
5832 if (IEEE80211_BAND_5GHZ == params->channel->band)
5833 {
5834 hddLog(VOS_TRACE_LEVEL_ERROR,
5835 "%s: IBSS join is called with unsupported band %d",
5836 __func__, params->channel->band);
5837 return -EOPNOTSUPP;
5838 }
5839
5840 /* Get channel number */
5841 channelNum =
5842 ieee80211_frequency_to_channel(params->channel->center_freq);
5843
5844 /*TODO: use macro*/
5845 if (14 >= channelNum)
5846 {
5847 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5848 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5849 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5850 int indx;
5851
5852 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5853 validChan, &numChans))
5854 {
5855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5856 __func__);
5857 return -EOPNOTSUPP;
5858 }
5859
5860 for (indx = 0; indx < numChans; indx++)
5861 {
5862 if (channelNum == validChan[indx])
5863 {
5864 break;
5865 }
5866 }
5867 if (indx >= numChans)
5868 {
5869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
5870 __func__, channelNum);
5871 return -EINVAL;
5872 }
5873 /* Set the Operational Channel */
5874 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5875 channelNum);
5876 pRoamProfile->ChannelInfo.numOfChannels = 1;
5877 pHddStaCtx->conn_info.operationChannel = channelNum;
5878 pRoamProfile->ChannelInfo.ChannelList =
5879 &pHddStaCtx->conn_info.operationChannel;
5880 }
5881 else
5882 {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
5884 __func__, channelNum);
5885 return -EINVAL;
5886 }
5887 }
5888
5889 /* Initialize security parameters */
5890 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
5891 if (status < 0)
5892 {
5893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
5894 __func__);
5895 return status;
5896 }
5897
5898 /* Issue connect start */
5899 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005900 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005901
5902 if (0 > status)
5903 {
5904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5905 return status;
5906 }
5907
5908 return 0;
5909}
5910
5911/*
5912 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
5913 * This function is used to leave an IBSS
5914 */
5915static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
5916 struct net_device *dev
5917 )
5918{
5919 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5920 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5921 tCsrRoamProfile *pRoamProfile;
5922
5923 ENTER();
5924
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005925 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5926 {
5927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5928 "%s:LOGP in Progress. Ignore!!!", __func__);
5929 return -EAGAIN;
5930 }
5931
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5933 if (NULL == pWextState)
5934 {
5935 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
5936 __func__);
5937 return -EIO;
5938 }
5939
5940 pRoamProfile = &pWextState->roamProfile;
5941
5942 /* Issue disconnect only if interface type is set to IBSS */
5943 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5944 {
5945 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
5946 __func__);
5947 return -EINVAL;
5948 }
5949
5950 /* Issue Disconnect request */
5951 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5952 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5953 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5954
5955 return 0;
5956}
5957
5958/*
5959 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5960 * This function is used to set the phy parameters
5961 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5962 */
5963static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
5964 u32 changed)
5965{
5966 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5967 tHalHandle hHal = pHddCtx->hHal;
5968
5969 ENTER();
5970
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005971 if ( pHddCtx->isLogpInProgress )
5972 {
5973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5974 "%s:LOGP in Progress. Ignore!!!", __func__);
5975 return -EAGAIN;
5976 }
5977
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5979 {
5980 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5981 WNI_CFG_RTS_THRESHOLD_STAMAX :
5982 wiphy->rts_threshold;
5983
5984 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
5985 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
5986 {
5987 hddLog(VOS_TRACE_LEVEL_ERROR,
5988 "%s: Invalid RTS Threshold value %hu",
5989 __func__, rts_threshold);
5990 return -EINVAL;
5991 }
5992
5993 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5994 rts_threshold, ccmCfgSetCallback,
5995 eANI_BOOLEAN_TRUE))
5996 {
5997 hddLog(VOS_TRACE_LEVEL_ERROR,
5998 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
5999 __func__, rts_threshold);
6000 return -EIO;
6001 }
6002
6003 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
6004 rts_threshold);
6005 }
6006
6007 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6008 {
6009 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6010 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6011 wiphy->frag_threshold;
6012
6013 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
6014 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
6015 {
6016 hddLog(VOS_TRACE_LEVEL_ERROR,
6017 "%s: Invalid frag_threshold value %hu", __func__,
6018 frag_threshold);
6019 return -EINVAL;
6020 }
6021
6022 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6023 frag_threshold, ccmCfgSetCallback,
6024 eANI_BOOLEAN_TRUE))
6025 {
6026 hddLog(VOS_TRACE_LEVEL_ERROR,
6027 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
6028 __func__, frag_threshold);
6029 return -EIO;
6030 }
6031
6032 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6033 frag_threshold);
6034 }
6035
6036 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6037 || (changed & WIPHY_PARAM_RETRY_LONG))
6038 {
6039 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6040 wiphy->retry_short :
6041 wiphy->retry_long;
6042
6043 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6044 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6045 {
6046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
6047 __func__, retry_value);
6048 return -EINVAL;
6049 }
6050
6051 if (changed & WIPHY_PARAM_RETRY_SHORT)
6052 {
6053 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6054 retry_value, ccmCfgSetCallback,
6055 eANI_BOOLEAN_TRUE))
6056 {
6057 hddLog(VOS_TRACE_LEVEL_ERROR,
6058 "%s: ccmCfgSetInt failed for long retry count %hu",
6059 __func__, retry_value);
6060 return -EIO;
6061 }
6062 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
6063 __func__, retry_value);
6064 }
6065 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6066 {
6067 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6068 retry_value, ccmCfgSetCallback,
6069 eANI_BOOLEAN_TRUE))
6070 {
6071 hddLog(VOS_TRACE_LEVEL_ERROR,
6072 "%s: ccmCfgSetInt failed for short retry count %hu",
6073 __func__, retry_value);
6074 return -EIO;
6075 }
6076 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
6077 __func__, retry_value);
6078 }
6079 }
6080
6081 return 0;
6082}
6083
6084/*
6085 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6086 * This function is used to set the txpower
6087 */
6088static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6089#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
6090 enum tx_power_setting type,
6091#else
6092 enum nl80211_tx_power_setting type,
6093#endif
6094 int dbm)
6095{
6096 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6097 tHalHandle hHal = pHddCtx->hHal;
6098 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6099 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6100
6101 ENTER();
6102
6103 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6104 dbm, ccmCfgSetCallback,
6105 eANI_BOOLEAN_TRUE))
6106 {
6107 hddLog(VOS_TRACE_LEVEL_ERROR,
6108 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6109 return -EIO;
6110 }
6111
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006112 if ( pHddCtx->isLogpInProgress )
6113 {
6114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6115 "%s:LOGP in Progress. Ignore!!!", __func__);
6116 return -EAGAIN;
6117 }
6118
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6120 dbm);
6121
6122 switch(type)
6123 {
6124 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6125 /* Fall through */
6126 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6127 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6128 {
6129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6130 __func__);
6131 return -EIO;
6132 }
6133 break;
6134 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
6135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
6136 __func__);
6137 return -EOPNOTSUPP;
6138 break;
6139 default:
6140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6141 __func__, type);
6142 return -EIO;
6143 }
6144
6145 return 0;
6146}
6147
6148/*
6149 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6150 * This function is used to read the txpower
6151 */
6152static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6153{
6154
6155 hdd_adapter_t *pAdapter;
6156 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6157
Jeff Johnsone7245742012-09-05 17:12:55 -07006158 ENTER();
6159
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 if (NULL == pHddCtx)
6161 {
6162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6163 *dbm = 0;
6164 return -ENOENT;
6165 }
6166
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006167 if ( pHddCtx->isLogpInProgress )
6168 {
6169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6170 "%s:LOGP in Progress. Ignore!!!", __func__);
6171 return -EAGAIN;
6172 }
6173
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6175 if (NULL == pAdapter)
6176 {
6177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6178 return -ENOENT;
6179 }
6180
6181 wlan_hdd_get_classAstats(pAdapter);
6182 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6183
Jeff Johnsone7245742012-09-05 17:12:55 -07006184 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 return 0;
6186}
6187
6188static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6189 u8* mac, struct station_info *sinfo)
6190{
6191 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6192 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6193 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6194 tANI_U8 rate_flags;
6195
6196 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6197 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006198
6199 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6200 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6201 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6202 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6203 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6204 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6205 tANI_U16 maxRate = 0;
6206 tANI_U16 myRate;
6207 tANI_U16 currentRate = 0;
6208 tANI_U8 maxSpeedMCS = 0;
6209 tANI_U8 maxMCSIdx = 0;
6210 tANI_U8 rateFlag = 1;
6211 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006212 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006213
Leo Chang6f8870f2013-03-26 18:11:36 -07006214#ifdef WLAN_FEATURE_11AC
6215 tANI_U32 vht_mcs_map;
6216 eDataRate11ACMaxMcs vhtMaxMcs;
6217#endif /* WLAN_FEATURE_11AC */
6218
Jeff Johnsone7245742012-09-05 17:12:55 -07006219 ENTER();
6220
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6222 (0 == ssidlen))
6223 {
6224 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6225 " Invalid ssidlen, %d", __func__, ssidlen);
6226 /*To keep GUI happy*/
6227 return 0;
6228 }
6229
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006230 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6231 {
6232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6233 "%s:LOGP in Progress. Ignore!!!", __func__);
6234 return -EAGAIN;
6235 }
6236
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6238 sinfo->filled |= STATION_INFO_SIGNAL;
6239
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006240 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6242
6243 //convert to the UI units of 100kbps
6244 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6245
6246#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006247 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 sinfo->signal,
6249 pCfg->reportMaxLinkSpeed,
6250 myRate,
6251 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006252 (int) pCfg->linkSpeedRssiMid,
6253 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006254 (int) rate_flags,
6255 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006256#endif //LINKSPEED_DEBUG_ENABLED
6257
6258 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6259 {
6260 // we do not want to necessarily report the current speed
6261 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6262 {
6263 // report the max possible speed
6264 rssidx = 0;
6265 }
6266 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6267 {
6268 // report the max possible speed with RSSI scaling
6269 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6270 {
6271 // report the max possible speed
6272 rssidx = 0;
6273 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006274 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 {
6276 // report middle speed
6277 rssidx = 1;
6278 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006279 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6280 {
6281 // report middle speed
6282 rssidx = 2;
6283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 else
6285 {
6286 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006287 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 }
6289 }
6290 else
6291 {
6292 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6293 hddLog(VOS_TRACE_LEVEL_ERROR,
6294 "%s: Invalid value for reportMaxLinkSpeed: %u",
6295 __func__, pCfg->reportMaxLinkSpeed);
6296 rssidx = 0;
6297 }
6298
6299 maxRate = 0;
6300
6301 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306302 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6303 OperationalRates, &ORLeng))
6304 {
6305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6306 /*To keep GUI happy*/
6307 return 0;
6308 }
6309
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 for (i = 0; i < ORLeng; i++)
6311 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006312 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 {
6314 /* Validate Rate Set */
6315 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6316 {
6317 currentRate = supported_data_rate[j].supported_rate[rssidx];
6318 break;
6319 }
6320 }
6321 /* Update MAX rate */
6322 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6323 }
6324
6325 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306326 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6327 ExtendedRates, &ERLeng))
6328 {
6329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6330 /*To keep GUI happy*/
6331 return 0;
6332 }
6333
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 for (i = 0; i < ERLeng; i++)
6335 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006336 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 {
6338 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6339 {
6340 currentRate = supported_data_rate[j].supported_rate[rssidx];
6341 break;
6342 }
6343 }
6344 /* Update MAX rate */
6345 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6346 }
6347
6348 /* Get MCS Rate Set -- but only if we are connected at MCS
6349 rates or if we are always reporting max speed or if we have
6350 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006351 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306353 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6354 MCSRates, &MCSLeng))
6355 {
6356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6357 /*To keep GUI happy*/
6358 return 0;
6359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006361#ifdef WLAN_FEATURE_11AC
6362 /* VHT80 rate has seperate rate table */
6363 if (rate_flags & eHAL_TX_RATE_VHT80)
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006365 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_rate[rateFlag];
6366 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
6367 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006369 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006371 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
6372 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006374 maxMCSIdx = 7;
6375 }
6376 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6377 {
6378 maxMCSIdx = 8;
6379 }
6380 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6381 {
6382 maxMCSIdx = 9;
6383 }
6384 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_rate[rateFlag];
6385 maxSpeedMCS = 1;
6386 if (currentRate > maxRate)
6387 {
6388 maxRate = currentRate;
6389 }
6390 }
6391 else
6392#endif /* WLAN_FEATURE_11AC */
6393 {
6394 if (rate_flags & eHAL_TX_RATE_HT40)
6395 {
6396 rateFlag |= 1;
6397 }
6398 if (rate_flags & eHAL_TX_RATE_SGI)
6399 {
6400 rateFlag |= 2;
6401 }
6402
6403 for (i = 0; i < MCSLeng; i++)
6404 {
6405 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6406 for (j = 0; j < temp; j++)
6407 {
6408 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6409 {
6410 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6411 break;
6412 }
6413 }
6414 if ((j < temp) && (currentRate > maxRate))
6415 {
6416 maxRate = currentRate;
6417 maxSpeedMCS = 1;
6418 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6419 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 }
6421 }
6422 }
6423
6424 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006425 if (((maxRate < myRate) && (0 == rssidx)) ||
6426 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 {
6428 maxRate = myRate;
6429 if (rate_flags & eHAL_TX_RATE_LEGACY)
6430 {
6431 maxSpeedMCS = 0;
6432 }
6433 else
6434 {
6435 maxSpeedMCS = 1;
6436 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6437 }
6438 }
6439
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006440 if ((!maxSpeedMCS) || (0 != rssidx))
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 {
6442 sinfo->txrate.legacy = maxRate;
6443#ifdef LINKSPEED_DEBUG_ENABLED
6444 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6445#endif //LINKSPEED_DEBUG_ENABLED
6446 }
6447 else
6448 {
6449 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006450#ifdef WLAN_FEATURE_11AC
6451 sinfo->txrate.nss = 1;
6452 if (rate_flags & eHAL_TX_RATE_VHT80)
6453 {
6454 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6455 }
6456 else
6457#endif /* WLAN_FEATURE_11AC */
6458 {
6459 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 if (rate_flags & eHAL_TX_RATE_SGI)
6462 {
6463 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6464 }
6465 if (rate_flags & eHAL_TX_RATE_HT40)
6466 {
6467 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6468 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006469#ifdef WLAN_FEATURE_11AC
6470 else if (rate_flags & eHAL_TX_RATE_VHT80)
6471 {
6472 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6473 }
6474#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006475#ifdef LINKSPEED_DEBUG_ENABLED
6476 pr_info("Reporting MCS rate %d flags %x\n",
6477 sinfo->txrate.mcs,
6478 sinfo->txrate.flags );
6479#endif //LINKSPEED_DEBUG_ENABLED
6480 }
6481 }
6482 else
6483 {
6484 // report current rate instead of max rate
6485
6486 if (rate_flags & eHAL_TX_RATE_LEGACY)
6487 {
6488 //provide to the UI in units of 100kbps
6489 sinfo->txrate.legacy = myRate;
6490#ifdef LINKSPEED_DEBUG_ENABLED
6491 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6492#endif //LINKSPEED_DEBUG_ENABLED
6493 }
6494 else
6495 {
6496 //must be MCS
6497 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006498#ifdef WLAN_FEATURE_11AC
6499 sinfo->txrate.nss = 1;
6500 if (rate_flags & eHAL_TX_RATE_VHT80)
6501 {
6502 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6503 }
6504 else
6505#endif /* WLAN_FEATURE_11AC */
6506 {
6507 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 if (rate_flags & eHAL_TX_RATE_SGI)
6510 {
6511 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6512 }
6513 if (rate_flags & eHAL_TX_RATE_HT40)
6514 {
6515 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6516 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006517#ifdef WLAN_FEATURE_11AC
6518 else if (rate_flags & eHAL_TX_RATE_VHT80)
6519 {
6520 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6521 }
6522#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006523#ifdef LINKSPEED_DEBUG_ENABLED
6524 pr_info("Reporting actual MCS rate %d flags %x\n",
6525 sinfo->txrate.mcs,
6526 sinfo->txrate.flags );
6527#endif //LINKSPEED_DEBUG_ENABLED
6528 }
6529 }
6530 sinfo->filled |= STATION_INFO_TX_BITRATE;
6531
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006532 sinfo->tx_packets =
6533 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6534 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6535 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6536 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6537
6538 sinfo->tx_retries =
6539 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6540 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6541 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6542 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6543
6544 sinfo->tx_failed =
6545 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6546 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6547 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6548 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6549
6550 sinfo->filled |=
6551 STATION_INFO_TX_PACKETS |
6552 STATION_INFO_TX_RETRIES |
6553 STATION_INFO_TX_FAILED;
6554
6555 EXIT();
6556 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006557}
6558
6559static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6560 struct net_device *dev, bool mode, v_SINT_t timeout)
6561{
6562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6563 VOS_STATUS vos_status;
6564
Jeff Johnsone7245742012-09-05 17:12:55 -07006565 ENTER();
6566
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 if (NULL == pAdapter)
6568 {
6569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6570 return -ENODEV;
6571 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006572 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6573 {
6574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6575 "%s:LOGP in Progress. Ignore!!!", __func__);
6576 return -EAGAIN;
6577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006578
6579 /**The get power cmd from the supplicant gets updated by the nl only
6580 *on successful execution of the function call
6581 *we are oppositely mapped w.r.t mode in the driver
6582 **/
6583 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6584
Jeff Johnsone7245742012-09-05 17:12:55 -07006585 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 if (VOS_STATUS_E_FAILURE == vos_status)
6587 {
6588 return -EINVAL;
6589 }
6590 return 0;
6591}
6592
6593
6594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6595static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6596 struct net_device *netdev,
6597 u8 key_index)
6598{
Jeff Johnsone7245742012-09-05 17:12:55 -07006599 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 return 0;
6601}
6602#endif //LINUX_VERSION_CODE
6603
6604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6605static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6606 struct net_device *dev,
6607 struct ieee80211_txq_params *params)
6608{
Jeff Johnsone7245742012-09-05 17:12:55 -07006609 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 return 0;
6611}
6612#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6613static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6614 struct ieee80211_txq_params *params)
6615{
Jeff Johnsone7245742012-09-05 17:12:55 -07006616 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 return 0;
6618}
6619#endif //LINUX_VERSION_CODE
6620
6621static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6622 struct net_device *dev, u8 *mac)
6623{
6624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006625 VOS_STATUS vos_status;
6626 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006627
Jeff Johnsone7245742012-09-05 17:12:55 -07006628 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6630 {
6631 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6632 return -EINVAL;
6633 }
6634
6635 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6636 {
6637 hddLog( LOGE,
6638 "%s: Wlan Load/Unload is in progress", __func__);
6639 return -EBUSY;
6640 }
6641
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006642 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6643 {
6644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6645 "%s:LOGP in Progress. Ignore!!!", __func__);
6646 return -EAGAIN;
6647 }
6648
Jeff Johnson295189b2012-06-20 16:38:30 -07006649 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 )
6652 {
6653 if( NULL == mac )
6654 {
6655 v_U16_t i;
6656 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6657 {
6658 if(pAdapter->aStaInfo[i].isUsed)
6659 {
6660 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6661 hddLog(VOS_TRACE_LEVEL_INFO,
6662 "%s: Delete STA with MAC::"
6663 "%02x:%02x:%02x:%02x:%02x:%02x",
6664 __func__,
6665 macAddr[0], macAddr[1], macAddr[2],
6666 macAddr[3], macAddr[4], macAddr[5]);
6667 hdd_softap_sta_deauth(pAdapter, macAddr);
6668 }
6669 }
6670 }
6671 else
6672 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006673
6674 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6675 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6676 {
6677 hddLog(VOS_TRACE_LEVEL_INFO,
6678 "%s: Skip this DEL STA as this is not used::"
6679 "%02x:%02x:%02x:%02x:%02x:%02x",
6680 __func__,
6681 mac[0], mac[1], mac[2],
6682 mac[3], mac[4], mac[5]);
6683 return -ENOENT;
6684 }
6685
6686 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6687 {
6688 hddLog(VOS_TRACE_LEVEL_INFO,
6689 "%s: Skip this DEL STA as deauth is in progress::"
6690 "%02x:%02x:%02x:%02x:%02x:%02x",
6691 __func__,
6692 mac[0], mac[1], mac[2],
6693 mac[3], mac[4], mac[5]);
6694 return -ENOENT;
6695 }
6696
6697 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6698
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 hddLog(VOS_TRACE_LEVEL_INFO,
6700 "%s: Delete STA with MAC::"
6701 "%02x:%02x:%02x:%02x:%02x:%02x",
6702 __func__,
6703 mac[0], mac[1], mac[2],
6704 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006705
6706 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6707 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6708 {
6709 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6710 hddLog(VOS_TRACE_LEVEL_INFO,
6711 "%s: STA removal failed for ::"
6712 "%02x:%02x:%02x:%02x:%02x:%02x",
6713 __func__,
6714 mac[0], mac[1], mac[2],
6715 mac[3], mac[4], mac[5]);
6716 return -ENOENT;
6717 }
6718
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 }
6720 }
6721
6722 EXIT();
6723
6724 return 0;
6725}
6726
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006727static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6728 struct net_device *dev, u8 *mac, struct station_parameters *params)
6729{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006730 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006731#ifdef FEATURE_WLAN_TDLS
6732 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006733 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006734 mask = params->sta_flags_mask;
6735
6736 set = params->sta_flags_set;
6737
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006738#ifdef WLAN_FEATURE_TDLS_DEBUG
6739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6740 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6741 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6742#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006743
6744 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6745 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006746 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006747 }
6748 }
6749#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006750 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006751}
6752
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006753
6754#ifdef FEATURE_WLAN_LFR
6755static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006756 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006757{
6758#define MAX_PMKSAIDS_IN_CACHE 8
6759 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07006760 static tANI_U32 i; // HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006761 tANI_U32 j=0;
6762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6763 tHalHandle halHandle;
6764 eHalStatus result;
6765 tANI_U8 BSSIDMatched = 0;
6766
Jeff Johnsone7245742012-09-05 17:12:55 -07006767 ENTER();
6768
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006769 // Validate pAdapter
6770 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6771 {
6772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6773 return -EINVAL;
6774 }
6775
6776 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6777 {
6778 hddLog( LOGE,
6779 "%s: Wlan Load/Unload is in progress", __func__);
6780 return -EBUSY;
6781 }
6782
6783 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6784 {
6785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6786 "%s:LOGP in Progress. Ignore!!!", __func__);
6787 return -EAGAIN;
6788 }
6789
6790 // Retrieve halHandle
6791 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6792
6793 for (j = 0; j < i; j++)
6794 {
6795 if(vos_mem_compare(PMKIDCache[j].BSSID,
6796 pmksa->bssid, WNI_CFG_BSSID_LEN))
6797 {
6798 /* BSSID matched previous entry. Overwrite it. */
6799 BSSIDMatched = 1;
6800 vos_mem_copy(PMKIDCache[j].BSSID,
6801 pmksa->bssid, WNI_CFG_BSSID_LEN);
6802 vos_mem_copy(PMKIDCache[j].PMKID,
6803 pmksa->pmkid,
6804 CSR_RSN_PMKID_SIZE);
6805 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006806 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006807 dump_bssid(pmksa->bssid);
6808 dump_pmkid(halHandle, pmksa->pmkid);
6809 break;
6810 }
6811 }
6812
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006813 /* Check we compared all entries,if then take the first slot now */
6814 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6815
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006816 if (!BSSIDMatched)
6817 {
6818 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6819 vos_mem_copy(PMKIDCache[i].BSSID,
6820 pmksa->bssid, ETHER_ADDR_LEN);
6821 vos_mem_copy(PMKIDCache[i].PMKID,
6822 pmksa->pmkid,
6823 CSR_RSN_PMKID_SIZE);
6824 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006825 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006826 dump_bssid(pmksa->bssid);
6827 dump_pmkid(halHandle, pmksa->pmkid);
6828 // Increment the HDD Local Cache index
6829 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
6830 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
6831 }
6832
6833
6834 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
6835 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006836 // __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006837 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006838 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006839 // Finally set the PMKSA ID Cache in CSR
6840 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6841 PMKIDCache,
6842 i );
6843 return 0;
6844}
6845
6846
6847static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006848 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006849{
Jeff Johnsone7245742012-09-05 17:12:55 -07006850 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006851 // TODO: Implement this later.
6852 return 0;
6853}
6854
6855static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6856{
Jeff Johnsone7245742012-09-05 17:12:55 -07006857 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006858 // TODO: Implement this later.
6859 return 0;
6860}
6861#endif
6862
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006863#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
6864static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
6865 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6866{
6867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6868 hdd_station_ctx_t *pHddStaCtx;
6869
6870 if (NULL == pAdapter)
6871 {
6872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6873 return -ENODEV;
6874 }
6875
6876 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6877
6878 // Added for debug on reception of Re-assoc Req.
6879 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6880 {
6881 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
6882 ftie->ie_len);
6883 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6884 }
6885
6886#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
6887 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
6888 ftie->ie_len);
6889#endif
6890
6891 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306892 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6893 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006894 ftie->ie_len);
6895 return 0;
6896}
6897#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006898
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006899#ifdef FEATURE_WLAN_TDLS
6900static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6901 u8 *peer, u8 action_code, u8 dialog_token,
6902 u16 status_code, const u8 *buf, size_t len)
6903{
6904
6905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6906 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006907 u8 peerMac[6];
6908 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006909 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006910 int responder;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006911
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006912 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006913 {
6914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6915 "Invalid arguments");
6916 return -EINVAL;
6917 }
6918
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006919 if (pHddCtx->isLogpInProgress)
6920 {
6921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6922 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006923 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006924 return -EBUSY;
6925 }
6926
Hoonki Lee27511902013-03-14 18:19:06 -07006927 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006928 {
Hoonki Lee27511902013-03-14 18:19:06 -07006929 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6930 "%s: TDLS mode is disabled OR not enabled in FW."
6931 MAC_ADDRESS_STR " action %d declined.",
6932 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006933 return -ENOTSUPP;
6934 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08006935
Hoonki Lee27511902013-03-14 18:19:06 -07006936 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
6937 (SIR_MAC_TDLS_DIS_RSP == action_code))
6938 {
6939 wlan_hdd_tdls_set_cap (pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
6940 }
6941
6942 /* other than teardown frame, other mgmt frames are not sent if disabled */
6943 if (SIR_MAC_TDLS_TEARDOWN != action_code)
6944 {
6945 /* if tdls_mode is disabled to respond to peer's request */
6946 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
6947 {
6948 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6949 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006950 " TDLS mode is disabled. action %d declined.",
6951 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07006952
6953 return -ENOTSUPP;
6954 }
6955 }
6956
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006957 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
6958 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006959 if (wlan_hdd_tdls_is_progress(pAdapter, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006960 {
6961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006962 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006963 " TDLS setup is ongoing. action %d declined.",
6964 __func__, MAC_ADDR_ARRAY(peer), action_code);
6965 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006966 }
6967 }
6968
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006969 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
6970 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08006971 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006972 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08006973 {
6974 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
6975 we return error code at 'add_station()'. Hence we have this
6976 check again in addtion to add_station().
6977 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006978 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08006979 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6981 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006982 " TDLS Max peer already connected. action %d declined.",
6983 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006984 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08006985 }
6986 else
6987 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006988 /* maximum reached. tweak to send error code to peer and return
6989 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006990 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6992 "%s: " MAC_ADDRESS_STR
6993 " TDLS Max peer already connected send response status %d",
6994 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006995 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006996 /* fall through to send setup resp with failure status
6997 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08006998 }
6999 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007000 else
7001 {
7002 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007003 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007004 if (pTdlsPeer && (eTDLS_LINK_CONNECTED == pTdlsPeer->link_status))
7005 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007007 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7008 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007009 return -EPERM;
7010 }
7011 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007012 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007013 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007014
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007015#ifdef WLAN_FEATURE_TDLS_DEBUG
7016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007017 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7018 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7019 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007020#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007021
Hoonki Leea34dd892013-02-05 22:56:02 -08007022 /*Except teardown responder will not be used so just make 0*/
7023 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007024 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007025 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007026 responder = wlan_hdd_tdls_get_responder(pAdapter, peerMac);
7027 if(-1 == responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08007028 {
7029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007030 "%s: " MAC_ADDRESS_STR " peer doesn't exist dialog_token %d status %d, len = %d",
7031 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
Hoonki Leea34dd892013-02-05 22:56:02 -08007032 dialog_token, status_code, len);
7033 return -EPERM;
7034 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007035 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007036
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007037 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7038
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007039 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007040 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007041
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007042 if (VOS_STATUS_SUCCESS != status)
7043 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7045 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007046 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007047 }
7048
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08007049 /* not block discovery request, as it is called from timer callback */
7050 if (SIR_MAC_TDLS_DIS_REQ != action_code)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007051 {
Pervinder Singhb4638422013-03-04 22:51:36 -08007052 long rc;
7053
7054 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08007055 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007056
Pervinder Singhb4638422013-03-04 22:51:36 -08007057 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08007058 {
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08007059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pervinder Singhb4638422013-03-04 22:51:36 -08007060 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7061 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007062 return -EPERM;
Gopichand Nakkalab88f6772013-02-27 18:12:56 -08007063 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007064 }
7065
Gopichand Nakkala05922802013-03-14 12:23:19 -07007066 if (max_sta_failed)
7067 return max_sta_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007068
Hoonki Leea34dd892013-02-05 22:56:02 -08007069 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7070 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007071 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007072 }
7073 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7074 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007075 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007076 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007077
7078 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007079error:
7080 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7081 because we already know that this transaction will be failed,
7082 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7083 to be safe, do not change the state mahine.
7084 */
7085 if(max_sta_failed == 0 &&
7086 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7087 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7088 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007089}
7090
7091static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7092 u8 *peer, enum nl80211_tdls_operation oper)
7093{
7094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7095 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007096#ifdef WLAN_FEATURE_TDLS_DEBUG
7097 const char *tdls_oper_str[]= {
7098 "NL80211_TDLS_DISCOVERY_REQ",
7099 "NL80211_TDLS_SETUP",
7100 "NL80211_TDLS_TEARDOWN",
7101 "NL80211_TDLS_ENABLE_LINK",
7102 "NL80211_TDLS_DISABLE_LINK",
7103 "NL80211_TDLS_UNKONW_OPER"};
7104#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007105
7106 if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
7107 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007109 "Invalid arguments");
7110 return -EINVAL;
7111 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007112
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007113 if (pHddCtx->isLogpInProgress)
7114 {
7115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7116 "%s:LOGP in Progress. Ignore!!!", __func__);
7117 return -EBUSY;
7118 }
7119
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007120#ifdef WLAN_FEATURE_TDLS_DEBUG
7121 if((int)oper > 4)
7122 oper = 5;
7123
7124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007125 "%s: " MAC_ADDRESS_STR " %d (%s) ", "tdls_oper",
7126 MAC_ADDR_ARRAY(peer), (int)oper,
7127 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007128#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007129
7130 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007131 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007132 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007134 "TDLS Disabled in INI OR not enabled in FW.\
7135 Cannot process TDLS commands \n");
7136 return -ENOTSUPP;
7137 }
7138
7139 switch (oper) {
7140 case NL80211_TDLS_ENABLE_LINK:
7141 {
Hoonki Lee387663d2013-02-05 18:08:43 -08007142 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007143 VOS_STATUS status;
7144
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007145 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007146
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007147 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7148 "%s: TDLS_LINK_ENABLE " MAC_ADDRESS_STR,
7149 __func__, MAC_ADDR_ARRAY(peer));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007150
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007151 if ( NULL == pTdlsPeer ) {
7152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer "
7153 MAC_ADDRESS_STR " failed",
7154 __func__, MAC_ADDR_ARRAY(peer));
7155 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007156 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007157
7158 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
7159 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007160 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007161 /* start TDLS client registration with TL */
7162 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007163 if (VOS_STATUS_SUCCESS == status)
7164 {
7165 wlan_hdd_tdls_increment_peer_count(pAdapter);
7166 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007167 wlan_hdd_tdls_check_bmps(pAdapter);
7168 }
7169
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007170 }
7171 break;
7172 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007173 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007174 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007175
7176 if(NULL != curr_peer)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007177 {
7178 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7179 pAdapter->sessionId, peer );
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08007180 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007181 }
7182 else
7183 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7185 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007186 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007187 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007188 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007189 case NL80211_TDLS_TEARDOWN:
7190 case NL80211_TDLS_SETUP:
7191 case NL80211_TDLS_DISCOVERY_REQ:
7192 /* We don't support in-driver setup/teardown/discovery */
7193 return -ENOTSUPP;
7194 default:
7195 return -ENOTSUPP;
7196 }
7197 return 0;
7198}
Chilam NG571c65a2013-01-19 12:27:36 +05307199
7200int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7201 struct net_device *dev, u8 *peer)
7202{
7203 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7204 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7205
7206 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7207 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7208}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007209#endif
7210
Jeff Johnson295189b2012-06-20 16:38:30 -07007211/* cfg80211_ops */
7212static struct cfg80211_ops wlan_hdd_cfg80211_ops =
7213{
7214 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7215 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7216 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7217 .change_station = wlan_hdd_change_station,
7218#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7219 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7220 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7221 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007222#else
7223 .start_ap = wlan_hdd_cfg80211_start_ap,
7224 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7225 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007226#endif
7227 .change_bss = wlan_hdd_cfg80211_change_bss,
7228 .add_key = wlan_hdd_cfg80211_add_key,
7229 .get_key = wlan_hdd_cfg80211_get_key,
7230 .del_key = wlan_hdd_cfg80211_del_key,
7231 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007232#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007234#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 .scan = wlan_hdd_cfg80211_scan,
7236 .connect = wlan_hdd_cfg80211_connect,
7237 .disconnect = wlan_hdd_cfg80211_disconnect,
7238 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7239 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7240 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7241 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7242 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7244 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7245 .mgmt_tx = wlan_hdd_action,
7246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7247 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7248 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7249 .set_txq_params = wlan_hdd_set_txq_params,
7250#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 .get_station = wlan_hdd_cfg80211_get_station,
7252 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7253 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007254 .add_station = wlan_hdd_cfg80211_add_station,
7255#ifdef FEATURE_WLAN_LFR
7256 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7257 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7258 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7259#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007260#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7261 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7262#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007263#ifdef FEATURE_WLAN_TDLS
7264 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7265 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007267};
7268