blob: 49a2abe7511c9de7908dfb4a5cd67164cef1a0ac [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 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
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070084#ifdef WLAN_BTAMP_FEATURE
85#include "bap_hdd_misc.h"
86#endif
87#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080088#ifdef FEATURE_WLAN_TDLS
89#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053090#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053091#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053093#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070094#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095
96#define g_mode_rates_size (12)
97#define a_mode_rates_size (8)
98#define FREQ_BASE_80211G (2407)
99#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700100#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530101#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800103 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700104
105#define HDD2GHZCHAN(freq, chan, flag) { \
106 .band = IEEE80211_BAND_2GHZ, \
107 .center_freq = (freq), \
108 .hw_value = (chan),\
109 .flags = (flag), \
110 .max_antenna_gain = 0 ,\
111 .max_power = 30, \
112}
113
114#define HDD5GHZCHAN(freq, chan, flag) { \
115 .band = IEEE80211_BAND_5GHZ, \
116 .center_freq = (freq), \
117 .hw_value = (chan),\
118 .flags = (flag), \
119 .max_antenna_gain = 0 ,\
120 .max_power = 30, \
121}
122
123#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
124{\
125 .bitrate = rate, \
126 .hw_value = rate_id, \
127 .flags = flag, \
128}
129
Lee Hoonkic1262f22013-01-24 21:59:00 -0800130#ifndef WLAN_FEATURE_TDLS_DEBUG
131#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
132#else
133#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
134#endif
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
142
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530143static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700144{
145 WLAN_CIPHER_SUITE_WEP40,
146 WLAN_CIPHER_SUITE_WEP104,
147 WLAN_CIPHER_SUITE_TKIP,
148#ifdef FEATURE_WLAN_CCX
149#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
150 WLAN_CIPHER_SUITE_KRK,
151 WLAN_CIPHER_SUITE_CCMP,
152#else
153 WLAN_CIPHER_SUITE_CCMP,
154#endif
155#ifdef FEATURE_WLAN_WAPI
156 WLAN_CIPHER_SUITE_SMS4,
157#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700158#ifdef WLAN_FEATURE_11W
159 WLAN_CIPHER_SUITE_AES_CMAC,
160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161};
162
163static inline int is_broadcast_ether_addr(const u8 *addr)
164{
165 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
166 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
167}
168
169static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530170{
Jeff Johnson295189b2012-06-20 16:38:30 -0700171 HDD2GHZCHAN(2412, 1, 0) ,
172 HDD2GHZCHAN(2417, 2, 0) ,
173 HDD2GHZCHAN(2422, 3, 0) ,
174 HDD2GHZCHAN(2427, 4, 0) ,
175 HDD2GHZCHAN(2432, 5, 0) ,
176 HDD2GHZCHAN(2437, 6, 0) ,
177 HDD2GHZCHAN(2442, 7, 0) ,
178 HDD2GHZCHAN(2447, 8, 0) ,
179 HDD2GHZCHAN(2452, 9, 0) ,
180 HDD2GHZCHAN(2457, 10, 0) ,
181 HDD2GHZCHAN(2462, 11, 0) ,
182 HDD2GHZCHAN(2467, 12, 0) ,
183 HDD2GHZCHAN(2472, 13, 0) ,
184 HDD2GHZCHAN(2484, 14, 0) ,
185};
186
Jeff Johnson295189b2012-06-20 16:38:30 -0700187static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
188{
189 HDD2GHZCHAN(2412, 1, 0) ,
190 HDD2GHZCHAN(2437, 6, 0) ,
191 HDD2GHZCHAN(2462, 11, 0) ,
192};
Jeff Johnson295189b2012-06-20 16:38:30 -0700193
194static struct ieee80211_channel hdd_channels_5_GHZ[] =
195{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700196 HDD5GHZCHAN(4920, 240, 0) ,
197 HDD5GHZCHAN(4940, 244, 0) ,
198 HDD5GHZCHAN(4960, 248, 0) ,
199 HDD5GHZCHAN(4980, 252, 0) ,
200 HDD5GHZCHAN(5040, 208, 0) ,
201 HDD5GHZCHAN(5060, 212, 0) ,
202 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD5GHZCHAN(5180, 36, 0) ,
204 HDD5GHZCHAN(5200, 40, 0) ,
205 HDD5GHZCHAN(5220, 44, 0) ,
206 HDD5GHZCHAN(5240, 48, 0) ,
207 HDD5GHZCHAN(5260, 52, 0) ,
208 HDD5GHZCHAN(5280, 56, 0) ,
209 HDD5GHZCHAN(5300, 60, 0) ,
210 HDD5GHZCHAN(5320, 64, 0) ,
211 HDD5GHZCHAN(5500,100, 0) ,
212 HDD5GHZCHAN(5520,104, 0) ,
213 HDD5GHZCHAN(5540,108, 0) ,
214 HDD5GHZCHAN(5560,112, 0) ,
215 HDD5GHZCHAN(5580,116, 0) ,
216 HDD5GHZCHAN(5600,120, 0) ,
217 HDD5GHZCHAN(5620,124, 0) ,
218 HDD5GHZCHAN(5640,128, 0) ,
219 HDD5GHZCHAN(5660,132, 0) ,
220 HDD5GHZCHAN(5680,136, 0) ,
221 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800222#ifdef FEATURE_WLAN_CH144
223 HDD5GHZCHAN(5720,144, 0) ,
224#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700225 HDD5GHZCHAN(5745,149, 0) ,
226 HDD5GHZCHAN(5765,153, 0) ,
227 HDD5GHZCHAN(5785,157, 0) ,
228 HDD5GHZCHAN(5805,161, 0) ,
229 HDD5GHZCHAN(5825,165, 0) ,
230};
231
232static struct ieee80211_rate g_mode_rates[] =
233{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530234 HDD_G_MODE_RATETAB(10, 0x1, 0),
235 HDD_G_MODE_RATETAB(20, 0x2, 0),
236 HDD_G_MODE_RATETAB(55, 0x4, 0),
237 HDD_G_MODE_RATETAB(110, 0x8, 0),
238 HDD_G_MODE_RATETAB(60, 0x10, 0),
239 HDD_G_MODE_RATETAB(90, 0x20, 0),
240 HDD_G_MODE_RATETAB(120, 0x40, 0),
241 HDD_G_MODE_RATETAB(180, 0x80, 0),
242 HDD_G_MODE_RATETAB(240, 0x100, 0),
243 HDD_G_MODE_RATETAB(360, 0x200, 0),
244 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530246};
Jeff Johnson295189b2012-06-20 16:38:30 -0700247
248static struct ieee80211_rate a_mode_rates[] =
249{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530250 HDD_G_MODE_RATETAB(60, 0x10, 0),
251 HDD_G_MODE_RATETAB(90, 0x20, 0),
252 HDD_G_MODE_RATETAB(120, 0x40, 0),
253 HDD_G_MODE_RATETAB(180, 0x80, 0),
254 HDD_G_MODE_RATETAB(240, 0x100, 0),
255 HDD_G_MODE_RATETAB(360, 0x200, 0),
256 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD_G_MODE_RATETAB(540, 0x800, 0),
258};
259
260static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
261{
262 .channels = hdd_channels_2_4_GHZ,
263 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
264 .band = IEEE80211_BAND_2GHZ,
265 .bitrates = g_mode_rates,
266 .n_bitrates = g_mode_rates_size,
267 .ht_cap.ht_supported = 1,
268 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
269 | IEEE80211_HT_CAP_GRN_FLD
270 | IEEE80211_HT_CAP_DSSSCCK40
271 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
272 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
273 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
274 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
275 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
276 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
277};
278
Jeff Johnson295189b2012-06-20 16:38:30 -0700279static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
280{
281 .channels = hdd_social_channels_2_4_GHZ,
282 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
283 .band = IEEE80211_BAND_2GHZ,
284 .bitrates = g_mode_rates,
285 .n_bitrates = g_mode_rates_size,
286 .ht_cap.ht_supported = 1,
287 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
288 | IEEE80211_HT_CAP_GRN_FLD
289 | IEEE80211_HT_CAP_DSSSCCK40
290 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
291 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
292 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
293 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
294 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
295 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
296};
Jeff Johnson295189b2012-06-20 16:38:30 -0700297
298static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
299{
300 .channels = hdd_channels_5_GHZ,
301 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
302 .band = IEEE80211_BAND_5GHZ,
303 .bitrates = a_mode_rates,
304 .n_bitrates = a_mode_rates_size,
305 .ht_cap.ht_supported = 1,
306 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
307 | IEEE80211_HT_CAP_GRN_FLD
308 | IEEE80211_HT_CAP_DSSSCCK40
309 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
310 | IEEE80211_HT_CAP_SGI_40
311 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
312 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
313 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
314 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
315 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
316 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
317};
318
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530319/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 TX/RX direction for each kind of interface */
321static const struct ieee80211_txrx_stypes
322wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
323 [NL80211_IFTYPE_STATION] = {
324 .tx = 0xffff,
325 .rx = BIT(SIR_MAC_MGMT_ACTION) |
326 BIT(SIR_MAC_MGMT_PROBE_REQ),
327 },
328 [NL80211_IFTYPE_AP] = {
329 .tx = 0xffff,
330 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
331 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
332 BIT(SIR_MAC_MGMT_PROBE_REQ) |
333 BIT(SIR_MAC_MGMT_DISASSOC) |
334 BIT(SIR_MAC_MGMT_AUTH) |
335 BIT(SIR_MAC_MGMT_DEAUTH) |
336 BIT(SIR_MAC_MGMT_ACTION),
337 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700338 [NL80211_IFTYPE_ADHOC] = {
339 .tx = 0xffff,
340 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
341 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
342 BIT(SIR_MAC_MGMT_PROBE_REQ) |
343 BIT(SIR_MAC_MGMT_DISASSOC) |
344 BIT(SIR_MAC_MGMT_AUTH) |
345 BIT(SIR_MAC_MGMT_DEAUTH) |
346 BIT(SIR_MAC_MGMT_ACTION),
347 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 [NL80211_IFTYPE_P2P_CLIENT] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_P2P_GO] = {
354 /* This is also same as for SoftAP */
355 .tx = 0xffff,
356 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ) |
359 BIT(SIR_MAC_MGMT_DISASSOC) |
360 BIT(SIR_MAC_MGMT_AUTH) |
361 BIT(SIR_MAC_MGMT_DEAUTH) |
362 BIT(SIR_MAC_MGMT_ACTION),
363 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700364};
365
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800367static const struct ieee80211_iface_limit
368wlan_hdd_iface_limit[] = {
369 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800370 /* max = 3 ; Our driver create two interfaces during driver init
371 * wlan0 and p2p0 interfaces. p2p0 is considered as station
372 * interface until a group is formed. In JB architecture, once the
373 * group is formed, interface type of p2p0 is changed to P2P GO or
374 * Client.
375 * When supplicant remove the group, it first issue a set interface
376 * cmd to change the mode back to Station. In JB this works fine as
377 * we advertize two station type interface during driver init.
378 * Some vendors create separate interface for P2P GO/Client,
379 * after group formation(Third one). But while group remove
380 * supplicant first tries to change the mode(3rd interface) to STATION
381 * But as we advertized only two sta type interfaces nl80211 was
382 * returning error for the third one which was leading to failure in
383 * delete interface. Ideally while removing the group, supplicant
384 * should not try to change the 3rd interface mode to Station type.
385 * Till we get a fix in wpa_supplicant, we advertize max STA
386 * interface type to 3
387 */
388 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389 .types = BIT(NL80211_IFTYPE_STATION),
390 },
391 {
392 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700393 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800394 },
395 {
396 .max = 1,
397 .types = BIT(NL80211_IFTYPE_P2P_GO) |
398 BIT(NL80211_IFTYPE_P2P_CLIENT),
399 },
400};
401
402/* By default, only single channel concurrency is allowed */
403static struct ieee80211_iface_combination
404wlan_hdd_iface_combination = {
405 .limits = wlan_hdd_iface_limit,
406 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800407 /*
408 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
409 * and p2p0 interfaces during driver init
410 * Some vendors create separate interface for P2P operations.
411 * wlan0: STA interface
412 * p2p0: P2P Device interface, action frames goes
413 * through this interface.
414 * p2p-xx: P2P interface, After GO negotiation this interface is
415 * created for p2p operations(GO/CLIENT interface).
416 */
417 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800418 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
419 .beacon_int_infra_match = false,
420};
421#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423static struct cfg80211_ops wlan_hdd_cfg80211_ops;
424
425/* Data rate 100KBPS based on IE Index */
426struct index_data_rate_type
427{
428 v_U8_t beacon_rate_index;
429 v_U16_t supported_rate[4];
430};
431
432/* 11B, 11G Rate table include Basic rate and Extended rate
433 The IDX field is the rate index
434 The HI field is the rate when RSSI is strong or being ignored
435 (in this case we report actual rate)
436 The MID field is the rate when RSSI is moderate
437 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
438 The LO field is the rate when RSSI is low
439 (in this case we don't report rates, actual current rate used)
440 */
441static const struct
442{
443 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700444 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700445} supported_data_rate[] =
446{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447/* IDX HI HM LM LO (RSSI-based index */
448 {2, { 10, 10, 10, 0}},
449 {4, { 20, 20, 10, 0}},
450 {11, { 55, 20, 10, 0}},
451 {12, { 60, 55, 20, 0}},
452 {18, { 90, 55, 20, 0}},
453 {22, {110, 55, 20, 0}},
454 {24, {120, 90, 60, 0}},
455 {36, {180, 120, 60, 0}},
456 {44, {220, 180, 60, 0}},
457 {48, {240, 180, 90, 0}},
458 {66, {330, 180, 90, 0}},
459 {72, {360, 240, 90, 0}},
460 {96, {480, 240, 120, 0}},
461 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700462};
463
464/* MCS Based rate table */
465static struct index_data_rate_type supported_mcs_rate[] =
466{
467/* MCS L20 L40 S20 S40 */
468 {0, {65, 135, 72, 150}},
469 {1, {130, 270, 144, 300}},
470 {2, {195, 405, 217, 450}},
471 {3, {260, 540, 289, 600}},
472 {4, {390, 810, 433, 900}},
473 {5, {520, 1080, 578, 1200}},
474 {6, {585, 1215, 650, 1350}},
475 {7, {650, 1350, 722, 1500}}
476};
477
Leo Chang6f8870f2013-03-26 18:11:36 -0700478#ifdef WLAN_FEATURE_11AC
479
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530480#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700481
482struct index_vht_data_rate_type
483{
484 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530485 v_U16_t supported_VHT80_rate[2];
486 v_U16_t supported_VHT40_rate[2];
487 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700488};
489
490typedef enum
491{
492 DATA_RATE_11AC_MAX_MCS_7,
493 DATA_RATE_11AC_MAX_MCS_8,
494 DATA_RATE_11AC_MAX_MCS_9,
495 DATA_RATE_11AC_MAX_MCS_NA
496} eDataRate11ACMaxMcs;
497
498/* MCS Based VHT rate table */
499static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
500{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530501/* MCS L80 S80 L40 S40 L20 S40*/
502 {0, {293, 325}, {135, 150}, {65, 72}},
503 {1, {585, 650}, {270, 300}, {130, 144}},
504 {2, {878, 975}, {405, 450}, {195, 217}},
505 {3, {1170, 1300}, {540, 600}, {260, 289}},
506 {4, {1755, 1950}, {810, 900}, {390, 433}},
507 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
508 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
509 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
510 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
511 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700512};
513#endif /* WLAN_FEATURE_11AC */
514
Jeff Johnson295189b2012-06-20 16:38:30 -0700515extern struct net_device_ops net_ops_struct;
516
Leo Chang9056f462013-08-01 19:21:11 -0700517#ifdef WLAN_NL80211_TESTMODE
518enum wlan_hdd_tm_attr
519{
520 WLAN_HDD_TM_ATTR_INVALID = 0,
521 WLAN_HDD_TM_ATTR_CMD = 1,
522 WLAN_HDD_TM_ATTR_DATA = 2,
523 WLAN_HDD_TM_ATTR_TYPE = 3,
524 /* keep last */
525 WLAN_HDD_TM_ATTR_AFTER_LAST,
526 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
527};
528
529enum wlan_hdd_tm_cmd
530{
531 WLAN_HDD_TM_CMD_WLAN_HB = 1,
532};
533
534#define WLAN_HDD_TM_DATA_MAX_LEN 5000
535
536static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
537{
538 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
539 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
540 .len = WLAN_HDD_TM_DATA_MAX_LEN },
541};
542#endif /* WLAN_NL80211_TESTMODE */
543
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800544#ifdef FEATURE_WLAN_CH_AVOID
545/*
546 * FUNCTION: wlan_hdd_send_avoid_freq_event
547 * This is called when wlan driver needs to send vendor specific
548 * avoid frequency range event to userspace
549 */
550int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
551 tHddAvoidFreqList *pAvoidFreqList)
552{
553 struct sk_buff *vendor_event;
554
555 ENTER();
556
557 if (!pHddCtx)
558 {
559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
560 "%s: HDD context is null", __func__);
561 return -1;
562 }
563
564 if (!pAvoidFreqList)
565 {
566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
567 "%s: pAvoidFreqList is null", __func__);
568 return -1;
569 }
570
571 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
572 sizeof(tHddAvoidFreqList),
573 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
574 GFP_KERNEL);
575 if (!vendor_event)
576 {
577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
578 "%s: cfg80211_vendor_event_alloc failed", __func__);
579 return -1;
580 }
581
582 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
583 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
584
585 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
586
587 EXIT();
588 return 0;
589}
590#endif /* FEATURE_WLAN_CH_AVOID */
591
592/* vendor specific events */
593static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
594{
595#ifdef FEATURE_WLAN_CH_AVOID
596 {
597 .vendor_id = QCOM_NL80211_VENDOR_ID,
598 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
599 },
600#endif /* FEATURE_WLAN_CH_AVOID */
601};
602
Jeff Johnson295189b2012-06-20 16:38:30 -0700603/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530604 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530605 * This function is called by hdd_wlan_startup()
606 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700608 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530609struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700610{
611 struct wiphy *wiphy;
612 ENTER();
613
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530614 /*
615 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700616 */
617 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
618
619 if (!wiphy)
620 {
621 /* Print error and jump into err label and free the memory */
622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
623 return NULL;
624 }
625
626 return wiphy;
627}
628
629/*
630 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530631 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700632 * private ioctl to change the band value
633 */
634int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
635{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530636 int i, j;
637 eNVChannelEnabledType channelEnabledState;
638
Jeff Johnsone7245742012-09-05 17:12:55 -0700639 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530640 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530642
643 if (NULL == wiphy->bands[i])
644 {
645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
646 __func__, i);
647 continue;
648 }
649
650 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
651 {
652 struct ieee80211_supported_band *band = wiphy->bands[i];
653
654 channelEnabledState = vos_nv_getChannelEnabledState(
655 band->channels[j].hw_value);
656
657 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
658 {
659 // Enable Social channels for P2P
660 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
661 NV_CHANNEL_ENABLE == channelEnabledState)
662 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
663 else
664 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
665 continue;
666 }
667 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
668 {
669 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
670 continue;
671 }
672
673 if (NV_CHANNEL_DISABLE == channelEnabledState ||
674 NV_CHANNEL_INVALID == channelEnabledState)
675 {
676 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
677 }
678 else if (NV_CHANNEL_DFS == channelEnabledState)
679 {
680 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
681 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
682 }
683 else
684 {
685 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
686 |IEEE80211_CHAN_RADAR);
687 }
688 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 }
690 return 0;
691}
692/*
693 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530694 * This function is called by hdd_wlan_startup()
695 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 * This function is used to initialize and register wiphy structure.
697 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530698int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 struct wiphy *wiphy,
700 hdd_config_t *pCfg
701 )
702{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530703 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530704 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
705
Jeff Johnsone7245742012-09-05 17:12:55 -0700706 ENTER();
707
Jeff Johnson295189b2012-06-20 16:38:30 -0700708 /* Now bind the underlying wlan device with wiphy */
709 set_wiphy_dev(wiphy, dev);
710
711 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700712
Kiet Lam6c583332013-10-14 05:37:09 +0530713#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700714 /* the flag for the other case would be initialzed in
715 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700716 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530717#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700718
Amar Singhalfddc28c2013-09-05 13:03:40 -0700719 /* This will disable updating of NL channels from passive to
720 * active if a beacon is received on passive channel. */
721 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700722
Amar Singhalfddc28c2013-09-05 13:03:40 -0700723
Amar Singhala49cbc52013-10-08 18:37:44 -0700724
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700726 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
727 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
728 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700729 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530730 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700731#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700732
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700733#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
734 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800735#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700736 || pCfg->isFastRoamIniFeatureEnabled
737#endif
738#ifdef FEATURE_WLAN_CCX
739 || pCfg->isCcxIniFeatureEnabled
740#endif
741 )
742 {
743 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
744 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800745#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800746#ifdef FEATURE_WLAN_TDLS
747 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
748 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
749#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530750#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530751 if (pCfg->configPNOScanSupport)
752 {
753 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
754 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
755 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
756 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
757 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530758#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800759
Amar Singhalfddc28c2013-09-05 13:03:40 -0700760#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700761 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
762 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 driver need to determine what to do with both
765 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766
767 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700768#else
769 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700770#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700771
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530772 wiphy->max_scan_ssids = MAX_SCAN_SSID;
773
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530774 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700775
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530776 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
777
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530779 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700780 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 | BIT(NL80211_IFTYPE_P2P_CLIENT)
782 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_AP);
784
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530785 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800786 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
788 if( pCfg->enableMCC )
789 {
790 /* Currently, supports up to two channels */
791 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800792
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530793 if( !pCfg->allowMCCGODiffBI )
794 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 }
797 wiphy->iface_combinations = &wlan_hdd_iface_combination;
798 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800799#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530800 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800801
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 /* Before registering we need to update the ht capabilitied based
803 * on ini values*/
804 if( !pCfg->ShortGI20MhzEnable )
805 {
806 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
807 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
808 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
809 }
810
811 if( !pCfg->ShortGI40MhzEnable )
812 {
813 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
814 }
815
816 if( !pCfg->nChannelBondingMode5GHz )
817 {
818 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
819 }
820
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530821 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530822 if (true == hdd_is_5g_supported(pHddCtx))
823 {
824 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
825 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530826
827 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
828 {
829
830 if (NULL == wiphy->bands[i])
831 {
832 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
833 __func__, i);
834 continue;
835 }
836
837 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
838 {
839 struct ieee80211_supported_band *band = wiphy->bands[i];
840
841 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
842 {
843 // Enable social channels for P2P
844 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
845 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
846 else
847 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
848 continue;
849 }
850 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
851 {
852 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
853 continue;
854 }
855 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700856 }
857 /*Initialise the supported cipher suite details*/
858 wiphy->cipher_suites = hdd_cipher_suites;
859 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
860
861 /*signal strength in mBm (100*dBm) */
862 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
863
864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700865 wiphy->max_remain_on_channel_duration = 1000;
866#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700867
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800868 wiphy->n_vendor_commands = 0;
869 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
870 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
871
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530872 EXIT();
873 return 0;
874}
875
876/* In this function we are registering wiphy. */
877int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
878{
879 ENTER();
880 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 if (0 > wiphy_register(wiphy))
882 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530883 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
885 return -EIO;
886 }
887
888 EXIT();
889 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530890}
Jeff Johnson295189b2012-06-20 16:38:30 -0700891
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530892/* In this function we are updating channel list when,
893 regulatory domain is FCC and country code is US.
894 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
895 As per FCC smart phone is not a indoor device.
896 GO should not opeate on indoor channels */
897void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
898{
899 int j;
900 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
901 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
902 //Default counrtycode from NV at the time of wiphy initialization.
903 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
904 &defaultCountryCode[0]))
905 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700906 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530907 }
908 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
909 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
911 {
912 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
913 return;
914 }
915 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
916 {
917 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
918 // Mark UNII -1 band channel as passive
919 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
920 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
921 }
922 }
923}
924
Jeff Johnson295189b2012-06-20 16:38:30 -0700925/* In this function we will do all post VOS start initialization.
926 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530927 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700928*/
929void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
930{
Jeff Johnson295189b2012-06-20 16:38:30 -0700931 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
932 /* Register for all P2P action, public action etc frames */
933 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
934
Jeff Johnsone7245742012-09-05 17:12:55 -0700935 ENTER();
936
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 /* Right now we are registering these frame when driver is getting
938 initialized. Once we will move to 2.6.37 kernel, in which we have
939 frame register ops, we will move this code as a part of that */
940 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530941 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
943
944 /* GAS Initial Response */
945 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
946 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530947
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 /* GAS Comeback Request */
949 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
950 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
951
952 /* GAS Comeback Response */
953 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
954 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
955
956 /* P2P Public Action */
957 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530958 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 P2P_PUBLIC_ACTION_FRAME_SIZE );
960
961 /* P2P Action */
962 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
963 (v_U8_t*)P2P_ACTION_FRAME,
964 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700965
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530966 /* WNM BSS Transition Request frame */
967 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
968 (v_U8_t*)WNM_BSS_ACTION_FRAME,
969 WNM_BSS_ACTION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700970}
971
972void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
973{
Jeff Johnson295189b2012-06-20 16:38:30 -0700974 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
975 /* Register for all P2P action, public action etc frames */
976 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
977
Jeff Johnsone7245742012-09-05 17:12:55 -0700978 ENTER();
979
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 /* Right now we are registering these frame when driver is getting
981 initialized. Once we will move to 2.6.37 kernel, in which we have
982 frame register ops, we will move this code as a part of that */
983 /* GAS Initial Request */
984
985 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
986 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
987
988 /* GAS Initial Response */
989 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
990 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530991
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 /* GAS Comeback Request */
993 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
994 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
995
996 /* GAS Comeback Response */
997 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
998 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
999
1000 /* P2P Public Action */
1001 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301002 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 P2P_PUBLIC_ACTION_FRAME_SIZE );
1004
1005 /* P2P Action */
1006 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1007 (v_U8_t*)P2P_ACTION_FRAME,
1008 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07001009
1010#ifdef WLAN_FEATURE_11W
1011 /* SA Query Response Action Frame */
1012 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1013 (v_U8_t*)SA_QUERY_FRAME_RSP,
1014 SA_QUERY_FRAME_RSP_SIZE );
1015#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001016}
1017
1018#ifdef FEATURE_WLAN_WAPI
1019void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1020 const u8 *mac_addr, u8 *key , int key_Len)
1021{
1022 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1023 tCsrRoamSetKey setKey;
1024 v_BOOL_t isConnected = TRUE;
1025 int status = 0;
1026 v_U32_t roamId= 0xFF;
1027 tANI_U8 *pKeyPtr = NULL;
1028 int n = 0;
1029
Arif Hussain6d2a3322013-11-17 19:50:10 -08001030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 __func__,pAdapter->device_mode);
1032
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301033 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 setKey.keyId = key_index; // Store Key ID
1035 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1036 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1037 setKey.paeRole = 0 ; // the PAE role
1038 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1039 {
1040 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1041 }
1042 else
1043 {
1044 isConnected = hdd_connIsConnected(pHddStaCtx);
1045 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1046 }
1047 setKey.keyLength = key_Len;
1048 pKeyPtr = setKey.Key;
1049 memcpy( pKeyPtr, key, key_Len);
1050
Arif Hussain6d2a3322013-11-17 19:50:10 -08001051 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 __func__, key_Len);
1053 for (n = 0 ; n < key_Len; n++)
1054 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1055 __func__,n,setKey.Key[n]);
1056
1057 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1058 if ( isConnected )
1059 {
1060 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1061 pAdapter->sessionId, &setKey, &roamId );
1062 }
1063 if ( status != 0 )
1064 {
1065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1066 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1067 __LINE__, status );
1068 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1069 }
1070}
1071#endif /* FEATURE_WLAN_WAPI*/
1072
1073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301074int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 beacon_data_t **ppBeacon,
1076 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001077#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301078int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001079 beacon_data_t **ppBeacon,
1080 struct cfg80211_beacon_data *params,
1081 int dtim_period)
1082#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301083{
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 int size;
1085 beacon_data_t *beacon = NULL;
1086 beacon_data_t *old = NULL;
1087 int head_len,tail_len;
1088
Jeff Johnsone7245742012-09-05 17:12:55 -07001089 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301091 {
1092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1093 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001094 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001096
1097 old = pAdapter->sessionCtx.ap.beacon;
1098
1099 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301100 {
1101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1102 FL("session(%d) old and new heads points to NULL"),
1103 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301105 }
1106
1107 if (params->tail && !params->tail_len)
1108 {
1109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1110 FL("tail_len is zero but tail is not NULL"));
1111 return -EINVAL;
1112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001113
Jeff Johnson295189b2012-06-20 16:38:30 -07001114#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1115 /* Kernel 3.0 is not updating dtim_period for set beacon */
1116 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301117 {
1118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1119 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001122#endif
1123
1124 if(params->head)
1125 head_len = params->head_len;
1126 else
1127 head_len = old->head_len;
1128
1129 if(params->tail || !old)
1130 tail_len = params->tail_len;
1131 else
1132 tail_len = old->tail_len;
1133
1134 size = sizeof(beacon_data_t) + head_len + tail_len;
1135
1136 beacon = kzalloc(size, GFP_KERNEL);
1137
1138 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301139 {
1140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1141 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001144
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001145#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001146 if(params->dtim_period || !old )
1147 beacon->dtim_period = params->dtim_period;
1148 else
1149 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001150#else
1151 if(dtim_period || !old )
1152 beacon->dtim_period = dtim_period;
1153 else
1154 beacon->dtim_period = old->dtim_period;
1155#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301156
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1158 beacon->tail = beacon->head + head_len;
1159 beacon->head_len = head_len;
1160 beacon->tail_len = tail_len;
1161
1162 if(params->head) {
1163 memcpy (beacon->head,params->head,beacon->head_len);
1164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301165 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 if(old)
1167 memcpy (beacon->head,old->head,beacon->head_len);
1168 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301169
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 if(params->tail) {
1171 memcpy (beacon->tail,params->tail,beacon->tail_len);
1172 }
1173 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301174 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 memcpy (beacon->tail,old->tail,beacon->tail_len);
1176 }
1177
1178 *ppBeacon = beacon;
1179
1180 kfree(old);
1181
1182 return 0;
1183
1184}
Jeff Johnson295189b2012-06-20 16:38:30 -07001185
1186v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1187{
1188 int left = length;
1189 v_U8_t *ptr = pIes;
1190 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301191
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301193 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 elem_id = ptr[0];
1195 elem_len = ptr[1];
1196 left -= 2;
1197 if(elem_len > left)
1198 {
1199 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001200 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 eid,elem_len,left);
1202 return NULL;
1203 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301204 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001205 {
1206 return ptr;
1207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301208
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 left -= elem_len;
1210 ptr += (elem_len + 2);
1211 }
1212 return NULL;
1213}
1214
Jeff Johnson295189b2012-06-20 16:38:30 -07001215/* Check if rate is 11g rate or not */
1216static int wlan_hdd_rate_is_11g(u8 rate)
1217{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001218 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 u8 i;
1220 for (i = 0; i < 8; i++)
1221 {
1222 if(rate == gRateArray[i])
1223 return TRUE;
1224 }
1225 return FALSE;
1226}
1227
1228/* Check for 11g rate and set proper 11g only mode */
1229static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1230 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1231{
1232 u8 i, num_rates = pIe[0];
1233
1234 pIe += 1;
1235 for ( i = 0; i < num_rates; i++)
1236 {
1237 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1238 {
1239 /* If rate set have 11g rate than change the mode to 11G */
1240 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1241 if (pIe[i] & BASIC_RATE_MASK)
1242 {
1243 /* If we have 11g rate as basic rate, it means mode
1244 is 11g only mode.
1245 */
1246 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1247 *pCheckRatesfor11g = FALSE;
1248 }
1249 }
1250 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1251 {
1252 *require_ht = TRUE;
1253 }
1254 }
1255 return;
1256}
1257
1258static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1259{
1260 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1261 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1262 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1263 u8 checkRatesfor11g = TRUE;
1264 u8 require_ht = FALSE;
1265 u8 *pIe=NULL;
1266
1267 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1268
1269 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1270 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1271 if (pIe != NULL)
1272 {
1273 pIe += 1;
1274 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1275 &pConfig->SapHw_mode);
1276 }
1277
1278 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1279 WLAN_EID_EXT_SUPP_RATES);
1280 if (pIe != NULL)
1281 {
1282
1283 pIe += 1;
1284 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1285 &pConfig->SapHw_mode);
1286 }
1287
1288 if( pConfig->channel > 14 )
1289 {
1290 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1291 }
1292
1293 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1294 WLAN_EID_HT_CAPABILITY);
1295
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301296 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 {
1298 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1299 if(require_ht)
1300 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1301 }
1302}
1303
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301304static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1305 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1306{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001307 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301308 v_U8_t *pIe = NULL;
1309 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1310
1311 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1312 pBeacon->tail, pBeacon->tail_len);
1313
1314 if (pIe)
1315 {
1316 ielen = pIe[1] + 2;
1317 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1318 {
1319 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1320 }
1321 else
1322 {
1323 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1324 return -EINVAL;
1325 }
1326 *total_ielen += ielen;
1327 }
1328 return 0;
1329}
1330
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001331static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1332 v_U8_t *genie, v_U8_t *total_ielen)
1333{
1334 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1335 int left = pBeacon->tail_len;
1336 v_U8_t *ptr = pBeacon->tail;
1337 v_U8_t elem_id, elem_len;
1338 v_U16_t ielen = 0;
1339
1340 if ( NULL == ptr || 0 == left )
1341 return;
1342
1343 while (left >= 2)
1344 {
1345 elem_id = ptr[0];
1346 elem_len = ptr[1];
1347 left -= 2;
1348 if (elem_len > left)
1349 {
1350 hddLog( VOS_TRACE_LEVEL_ERROR,
1351 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1352 elem_id, elem_len, left);
1353 return;
1354 }
1355 if (IE_EID_VENDOR == elem_id)
1356 {
1357 /* skipping the VSIE's which we don't want to include or
1358 * it will be included by existing code
1359 */
1360 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1361#ifdef WLAN_FEATURE_WFD
1362 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1363#endif
1364 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1365 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1366 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1367 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1368 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1369 {
1370 ielen = ptr[1] + 2;
1371 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1372 {
1373 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1374 *total_ielen += ielen;
1375 }
1376 else
1377 {
1378 hddLog( VOS_TRACE_LEVEL_ERROR,
1379 "IE Length is too big "
1380 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1381 elem_id, elem_len, *total_ielen);
1382 }
1383 }
1384 }
1385
1386 left -= elem_len;
1387 ptr += (elem_len + 2);
1388 }
1389 return;
1390}
1391
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001392#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001393static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1394 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001395#else
1396static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1397 struct cfg80211_beacon_data *params)
1398#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001399{
1400 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301401 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001403 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001404
1405 genie = vos_mem_malloc(MAX_GENIE_LEN);
1406
1407 if(genie == NULL) {
1408
1409 return -ENOMEM;
1410 }
1411
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301412 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1413 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001414 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301415 hddLog(LOGE,
1416 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301417 ret = -EINVAL;
1418 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001419 }
1420
1421#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301422 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1423 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1424 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301425 hddLog(LOGE,
1426 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301427 ret = -EINVAL;
1428 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 }
1430#endif
1431
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301432 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1433 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001434 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301435 hddLog(LOGE,
1436 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301437 ret = -EINVAL;
1438 goto done;
1439 }
1440
1441 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1442 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001443 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001445
1446 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1447 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1448 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1449 {
1450 hddLog(LOGE,
1451 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001452 ret = -EINVAL;
1453 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001454 }
1455
1456 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1457 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1458 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1459 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1460 ==eHAL_STATUS_FAILURE)
1461 {
1462 hddLog(LOGE,
1463 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001464 ret = -EINVAL;
1465 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 }
1467
1468 // Added for ProResp IE
1469 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1470 {
1471 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1472 u8 probe_rsp_ie_len[3] = {0};
1473 u8 counter = 0;
1474 /* Check Probe Resp Length if it is greater then 255 then Store
1475 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1476 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1477 Store More then 255 bytes into One Variable.
1478 */
1479 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1480 {
1481 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1482 {
1483 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1484 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1485 }
1486 else
1487 {
1488 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1489 rem_probe_resp_ie_len = 0;
1490 }
1491 }
1492
1493 rem_probe_resp_ie_len = 0;
1494
1495 if (probe_rsp_ie_len[0] > 0)
1496 {
1497 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1498 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1499 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1500 probe_rsp_ie_len[0], NULL,
1501 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1502 {
1503 hddLog(LOGE,
1504 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001505 ret = -EINVAL;
1506 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 }
1508 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1509 }
1510
1511 if (probe_rsp_ie_len[1] > 0)
1512 {
1513 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1514 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1515 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1516 probe_rsp_ie_len[1], NULL,
1517 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1518 {
1519 hddLog(LOGE,
1520 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001521 ret = -EINVAL;
1522 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 }
1524 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1525 }
1526
1527 if (probe_rsp_ie_len[2] > 0)
1528 {
1529 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1530 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1531 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1532 probe_rsp_ie_len[2], NULL,
1533 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1534 {
1535 hddLog(LOGE,
1536 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001537 ret = -EINVAL;
1538 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 }
1540 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1541 }
1542
1543 if (probe_rsp_ie_len[1] == 0 )
1544 {
1545 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1546 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1547 eANI_BOOLEAN_FALSE) )
1548 {
1549 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001550 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001551 }
1552 }
1553
1554 if (probe_rsp_ie_len[2] == 0 )
1555 {
1556 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1557 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1558 eANI_BOOLEAN_FALSE) )
1559 {
1560 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001561 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001562 }
1563 }
1564
1565 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1566 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1567 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1568 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1569 == eHAL_STATUS_FAILURE)
1570 {
1571 hddLog(LOGE,
1572 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001573 ret = -EINVAL;
1574 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 }
1576 }
1577 else
1578 {
1579 // Reset WNI_CFG_PROBE_RSP Flags
1580 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1581
1582 hddLog(VOS_TRACE_LEVEL_INFO,
1583 "%s: No Probe Response IE received in set beacon",
1584 __func__);
1585 }
1586
1587 // Added for AssocResp IE
1588 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1589 {
1590 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1591 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1592 params->assocresp_ies_len, NULL,
1593 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1594 {
1595 hddLog(LOGE,
1596 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001597 ret = -EINVAL;
1598 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 }
1600
1601 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1602 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1603 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1604 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1605 == eHAL_STATUS_FAILURE)
1606 {
1607 hddLog(LOGE,
1608 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001609 ret = -EINVAL;
1610 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 }
1612 }
1613 else
1614 {
1615 hddLog(VOS_TRACE_LEVEL_INFO,
1616 "%s: No Assoc Response IE received in set beacon",
1617 __func__);
1618
1619 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1620 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1621 eANI_BOOLEAN_FALSE) )
1622 {
1623 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001624 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001625 }
1626 }
1627
Jeff Johnsone7245742012-09-05 17:12:55 -07001628done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301630 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001631}
Jeff Johnson295189b2012-06-20 16:38:30 -07001632
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301633/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 * FUNCTION: wlan_hdd_validate_operation_channel
1635 * called by wlan_hdd_cfg80211_start_bss() and
1636 * wlan_hdd_cfg80211_set_channel()
1637 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301638 * channel list.
1639 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001640VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001641{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301642
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 v_U32_t num_ch = 0;
1644 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1645 u32 indx = 0;
1646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301647 v_U8_t fValidChannel = FALSE, count = 0;
1648 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301649
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1651
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301652 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301654 /* Validate the channel */
1655 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301657 if ( channel == rfChannels[count].channelNum )
1658 {
1659 fValidChannel = TRUE;
1660 break;
1661 }
1662 }
1663 if (fValidChannel != TRUE)
1664 {
1665 hddLog(VOS_TRACE_LEVEL_ERROR,
1666 "%s: Invalid Channel [%d]", __func__, channel);
1667 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 }
1669 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301670 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301672 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1673 valid_ch, &num_ch))
1674 {
1675 hddLog(VOS_TRACE_LEVEL_ERROR,
1676 "%s: failed to get valid channel list", __func__);
1677 return VOS_STATUS_E_FAILURE;
1678 }
1679 for (indx = 0; indx < num_ch; indx++)
1680 {
1681 if (channel == valid_ch[indx])
1682 {
1683 break;
1684 }
1685 }
1686
1687 if (indx >= num_ch)
1688 {
1689 hddLog(VOS_TRACE_LEVEL_ERROR,
1690 "%s: Invalid Channel [%d]", __func__, channel);
1691 return VOS_STATUS_E_FAILURE;
1692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001693 }
1694 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301695
Jeff Johnson295189b2012-06-20 16:38:30 -07001696}
1697
Viral Modi3a32cc52013-02-08 11:14:52 -08001698/**
1699 * FUNCTION: wlan_hdd_cfg80211_set_channel
1700 * This function is used to set the channel number
1701 */
1702static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1703 struct ieee80211_channel *chan,
1704 enum nl80211_channel_type channel_type
1705 )
1706{
1707 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001708 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001709 hdd_adapter_t *pAdapter = NULL;
1710 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301711 hdd_context_t *pHddCtx;
1712 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001713
1714 ENTER();
1715
1716 if( NULL == dev )
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001719 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001720 return -ENODEV;
1721 }
1722 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1723
1724 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001725 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001726 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301727
1728 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1729 status = wlan_hdd_validate_context(pHddCtx);
1730
1731 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001732 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1734 "%s: HDD context is not valid", __func__);
1735 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001736 }
1737
1738 /*
1739 * Do freq to chan conversion
1740 * TODO: for 11a
1741 */
1742
1743 channel = ieee80211_frequency_to_channel(freq);
1744
1745 /* Check freq range */
1746 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1747 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001750 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001751 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1752 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1753 return -EINVAL;
1754 }
1755
1756 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1757
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301758 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1759 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001760 {
1761 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1762 {
1763 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001764 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001765 return -EINVAL;
1766 }
1767 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1768 "%s: set channel to [%d] for device mode =%d",
1769 __func__, channel,pAdapter->device_mode);
1770 }
1771 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001772 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001773 )
1774 {
1775 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1776 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1777 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1778
1779 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1780 {
1781 /* Link is up then return cant set channel*/
1782 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001783 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001784 return -EINVAL;
1785 }
1786
1787 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1788 pHddStaCtx->conn_info.operationChannel = channel;
1789 pRoamProfile->ChannelInfo.ChannelList =
1790 &pHddStaCtx->conn_info.operationChannel;
1791 }
1792 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001793 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001794 )
1795 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301796 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1797 {
1798 if(VOS_STATUS_SUCCESS !=
1799 wlan_hdd_validate_operation_channel(pAdapter,channel))
1800 {
1801 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001802 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301803 return -EINVAL;
1804 }
1805 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1806 }
1807 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001808 {
1809 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1810
1811 /* If auto channel selection is configured as enable/ 1 then ignore
1812 channel set by supplicant
1813 */
1814 if ( cfg_param->apAutoChannelSelection )
1815 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301816 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1817 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001818 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1819 "%s: set channel to auto channel (0) for device mode =%d",
1820 __func__, pAdapter->device_mode);
1821 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301822 else
1823 {
1824 if(VOS_STATUS_SUCCESS !=
1825 wlan_hdd_validate_operation_channel(pAdapter,channel))
1826 {
1827 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001828 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301829 return -EINVAL;
1830 }
1831 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1832 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001833 }
1834 }
1835 else
1836 {
1837 hddLog(VOS_TRACE_LEVEL_FATAL,
1838 "%s: Invalid device mode failed to set valid channel", __func__);
1839 return -EINVAL;
1840 }
1841 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301842 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001843}
1844
Jeff Johnson295189b2012-06-20 16:38:30 -07001845#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1846static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1847 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001848#else
1849static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1850 struct cfg80211_beacon_data *params,
1851 const u8 *ssid, size_t ssid_len,
1852 enum nl80211_hidden_ssid hidden_ssid)
1853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001854{
1855 tsap_Config_t *pConfig;
1856 beacon_data_t *pBeacon = NULL;
1857 struct ieee80211_mgmt *pMgmt_frame;
1858 v_U8_t *pIe=NULL;
1859 v_U16_t capab_info;
1860 eCsrAuthType RSNAuthType;
1861 eCsrEncryptionType RSNEncryptType;
1862 eCsrEncryptionType mcRSNEncryptType;
1863 int status = VOS_STATUS_SUCCESS;
1864 tpWLAN_SAPEventCB pSapEventCallback;
1865 hdd_hostapd_state_t *pHostapdState;
1866 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1867 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301868 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001869 struct qc_mac_acl_entry *acl_entry = NULL;
1870 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001871 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001872 v_BOOL_t MFPCapable;
1873 v_BOOL_t MFPRequired;
Jeff Johnson295189b2012-06-20 16:38:30 -07001874
1875 ENTER();
1876
1877 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1878
1879 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1880
1881 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1882
1883 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1884
1885 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1886
1887 //channel is already set in the set_channel Call back
1888 //pConfig->channel = pCommitConfig->channel;
1889
1890 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301891 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1893
1894 pConfig->dtim_period = pBeacon->dtim_period;
1895
Arif Hussain6d2a3322013-11-17 19:50:10 -08001896 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 pConfig->dtim_period);
1898
1899
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001900 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001901 {
1902 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001903 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301904 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1905 {
1906 tANI_BOOLEAN restartNeeded;
1907 pConfig->ieee80211d = 1;
1908 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1909 sme_setRegInfo(hHal, pConfig->countryCode);
1910 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1911 }
1912 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001914 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001915 pConfig->ieee80211d = 1;
1916 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1917 sme_setRegInfo(hHal, pConfig->countryCode);
1918 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001920 else
1921 {
1922 pConfig->ieee80211d = 0;
1923 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301924 /*
1925 * If auto channel is configured i.e. channel is 0,
1926 * so skip channel validation.
1927 */
1928 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1929 {
1930 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1931 {
1932 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001933 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301934 return -EINVAL;
1935 }
1936 }
1937 else
1938 {
1939 if(1 != pHddCtx->is_dynamic_channel_range_set)
1940 {
1941 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1942 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1943 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1944 }
1945 pHddCtx->is_dynamic_channel_range_set = 0;
1946 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001948 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 {
1950 pConfig->ieee80211d = 0;
1951 }
1952 pConfig->authType = eSAP_AUTO_SWITCH;
1953
1954 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301955
1956 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1958
1959 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1960
1961 /*Set wps station to configured*/
1962 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1963
1964 if(pIe)
1965 {
1966 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1967 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001968 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 return -EINVAL;
1970 }
1971 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1972 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001973 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 /* Check 15 bit of WPS IE as it contain information for wps state
1975 * WPS state
1976 */
1977 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1978 {
1979 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1980 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1981 {
1982 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1983 }
1984 }
1985 }
1986 else
1987 {
1988 pConfig->wps_state = SAP_WPS_DISABLED;
1989 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301990 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001991
1992 pConfig->RSNWPAReqIELength = 0;
1993 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301994 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 WLAN_EID_RSN);
1996 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301997 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001998 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1999 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2000 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302001 /* The actual processing may eventually be more extensive than
2002 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 * by the app.
2004 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302005 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002006 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2007 &RSNEncryptType,
2008 &mcRSNEncryptType,
2009 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002010 &MFPCapable,
2011 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 pConfig->pRSNWPAReqIE[1]+2,
2013 pConfig->pRSNWPAReqIE );
2014
2015 if( VOS_STATUS_SUCCESS == status )
2016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302017 /* Now copy over all the security attributes you have
2018 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 * */
2020 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2021 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2022 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2023 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302024 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002025 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2027 }
2028 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302029
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2031 pBeacon->tail, pBeacon->tail_len);
2032
2033 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2034 {
2035 if (pConfig->pRSNWPAReqIE)
2036 {
2037 /*Mixed mode WPA/WPA2*/
2038 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2039 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2040 }
2041 else
2042 {
2043 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2044 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2045 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302046 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002047 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2048 &RSNEncryptType,
2049 &mcRSNEncryptType,
2050 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002051 &MFPCapable,
2052 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 pConfig->pRSNWPAReqIE[1]+2,
2054 pConfig->pRSNWPAReqIE );
2055
2056 if( VOS_STATUS_SUCCESS == status )
2057 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302058 /* Now copy over all the security attributes you have
2059 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002060 * */
2061 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2062 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2063 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2064 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302065 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002066 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2068 }
2069 }
2070 }
2071
Jeff Johnson4416a782013-03-25 14:17:50 -07002072 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2073 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2074 return -EINVAL;
2075 }
2076
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2078
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 if (params->ssid != NULL)
2081 {
2082 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2083 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2084 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2085 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2086 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002087#else
2088 if (ssid != NULL)
2089 {
2090 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2091 pConfig->SSIDinfo.ssid.length = ssid_len;
2092 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2093 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2094 }
2095#endif
2096
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302097 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302099
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 /* default value */
2101 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2102 pConfig->num_accept_mac = 0;
2103 pConfig->num_deny_mac = 0;
2104
2105 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2106 pBeacon->tail, pBeacon->tail_len);
2107
2108 /* pIe for black list is following form:
2109 type : 1 byte
2110 length : 1 byte
2111 OUI : 4 bytes
2112 acl type : 1 byte
2113 no of mac addr in black list: 1 byte
2114 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302115 */
2116 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002117 {
2118 pConfig->SapMacaddr_acl = pIe[6];
2119 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002120 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302122 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2123 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2125 for (i = 0; i < pConfig->num_deny_mac; i++)
2126 {
2127 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2128 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 }
2131 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2132 pBeacon->tail, pBeacon->tail_len);
2133
2134 /* pIe for white list is following form:
2135 type : 1 byte
2136 length : 1 byte
2137 OUI : 4 bytes
2138 acl type : 1 byte
2139 no of mac addr in white list: 1 byte
2140 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302141 */
2142 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002143 {
2144 pConfig->SapMacaddr_acl = pIe[6];
2145 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002146 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302148 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2149 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2151 for (i = 0; i < pConfig->num_accept_mac; i++)
2152 {
2153 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2154 acl_entry++;
2155 }
2156 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302157
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2159
Jeff Johnsone7245742012-09-05 17:12:55 -07002160#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002161 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302162 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2163 * 11ac in .ini and 11ac is supported by both host and firmware.
2164 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2165 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002166 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2167 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302168 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002169 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
Kiet Lam0f320422013-11-21 19:29:17 +05302170 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) &&
2171 (sme_IsFeatureSupportedByDriver(DOT11AC)) && (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002172 {
2173 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002174
2175 /* Disable VHT support in 2.4 GHz band */
2176 if (pConfig->channel <= 14 &&
2177 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2178 {
2179 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2180 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002181 }
2182#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302183
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002184 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2185 {
2186 sme_SelectCBMode(hHal,
2187 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2188 pConfig->channel);
2189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 // ht_capab is not what the name conveys,this is used for protection bitmap
2191 pConfig->ht_capab =
2192 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2193
2194 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2195 {
2196 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2197 return -EINVAL;
2198 }
2199
2200 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302201 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2203 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302204 pConfig->obssProtEnabled =
2205 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002206
Chet Lanctot8cecea22014-02-11 19:09:36 -08002207#ifdef WLAN_FEATURE_11W
2208 pConfig->mfpCapable = MFPCapable;
2209 pConfig->mfpRequired = MFPRequired;
2210 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2211 pConfig->mfpCapable, pConfig->mfpRequired);
2212#endif
2213
Arif Hussain6d2a3322013-11-17 19:50:10 -08002214 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002216 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2217 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2218 (int)pConfig->channel);
2219 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2220 pConfig->SapHw_mode, pConfig->privacy,
2221 pConfig->authType);
2222 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2223 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2224 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2225 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002226
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302227 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 {
2229 //Bss already started. just return.
2230 //TODO Probably it should update some beacon params.
2231 hddLog( LOGE, "Bss Already started...Ignore the request");
2232 EXIT();
2233 return 0;
2234 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302235
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 pConfig->persona = pHostapdAdapter->device_mode;
2237
2238 pSapEventCallback = hdd_hostapd_SAPEventCB;
2239 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2240 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2241 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002242 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 return -EINVAL;
2244 }
2245
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302246 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002247 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2248
2249 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302250
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302252 {
2253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002254 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002255 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 VOS_ASSERT(0);
2257 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302258
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 //Succesfully started Bss update the state bit.
2260 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2261
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002262#ifdef WLAN_FEATURE_P2P_DEBUG
2263 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2264 {
2265 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2266 {
2267 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2268 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002269 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002270 }
2271 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2272 {
2273 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2274 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002275 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002276 }
2277 }
2278#endif
2279
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 pHostapdState->bCommit = TRUE;
2281 EXIT();
2282
2283 return 0;
2284}
2285
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002286#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302287static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2288 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 struct beacon_parameters *params)
2290{
2291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302292 hdd_context_t *pHddCtx;
2293 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002294
2295 ENTER();
2296
Arif Hussain6d2a3322013-11-17 19:50:10 -08002297 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302299 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2300 status = wlan_hdd_validate_context(pHddCtx);
2301
2302 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002303 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2305 "%s: HDD context is not valid", __func__);
2306 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002307 }
2308
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302309 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 )
2312 {
2313 beacon_data_t *old,*new;
2314
2315 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302316
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302318 {
2319 hddLog(VOS_TRACE_LEVEL_WARN,
2320 FL("already beacon info added to session(%d)"),
2321 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002324
2325 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2326
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302327 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002328 {
2329 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002330 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002331 return -EINVAL;
2332 }
2333
2334 pAdapter->sessionCtx.ap.beacon = new;
2335
2336 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2337 }
2338
2339 EXIT();
2340 return status;
2341}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302342
2343static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 struct net_device *dev,
2345 struct beacon_parameters *params)
2346{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302348 hdd_context_t *pHddCtx;
2349 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002350
2351 ENTER();
2352
Arif Hussain6d2a3322013-11-17 19:50:10 -08002353 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 __func__,pAdapter->device_mode);
2355
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302356 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2357 status = wlan_hdd_validate_context(pHddCtx);
2358
2359 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2362 "%s: HDD context is not valid", __func__);
2363 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364 }
2365
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302366 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002367 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302368 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002369 {
2370 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302371
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302373
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302375 {
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 FL("session(%d) old and new heads points to NULL"),
2378 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002381
2382 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2383
2384 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302385 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002386 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002387 return -EINVAL;
2388 }
2389
2390 pAdapter->sessionCtx.ap.beacon = new;
2391
2392 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2393 }
2394
2395 EXIT();
2396 return status;
2397}
2398
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002399#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2400
2401#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002402static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2403 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002404#else
2405static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2406 struct net_device *dev)
2407#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002408{
2409 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002410 hdd_context_t *pHddCtx = NULL;
2411 hdd_scaninfo_t *pScanInfo = NULL;
2412 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302413 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002414
2415 ENTER();
2416
2417 if (NULL == pAdapter)
2418 {
2419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002420 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 return -ENODEV;
2422 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002423
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302424 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2425 status = wlan_hdd_validate_context(pHddCtx);
2426
2427 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: HDD context is not valid", __func__);
2431 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002432 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002433
2434 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2435 if (NULL == staAdapter)
2436 {
2437 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2438 if (NULL == staAdapter)
2439 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2441 "%s: HDD adapter context for STA/P2P-CLI is Null",
2442 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002443 }
2444 }
2445
2446 pScanInfo = &pHddCtx->scan_info;
2447
Arif Hussain6d2a3322013-11-17 19:50:10 -08002448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002449 __func__,pAdapter->device_mode);
2450
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002451 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002452 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302453 long ret;
2454
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002455 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302456 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2457 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302458 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002459 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002460 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302461 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002462 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302464 FL("Timeout occurred while waiting for abortscan %ld"),
2465 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002466
2467 if (pHddCtx->isLogpInProgress)
2468 {
2469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2470 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302471
2472 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002473 return -EAGAIN;
2474 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002475 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002476 }
2477 }
2478
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302479 hdd_hostapd_stop(dev);
2480
Jeff Johnson295189b2012-06-20 16:38:30 -07002481 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002483 )
2484 {
2485 beacon_data_t *old;
2486
2487 old = pAdapter->sessionCtx.ap.beacon;
2488
2489 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302490 {
2491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2492 FL("session(%d) beacon data points to NULL"),
2493 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002494 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002496
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002498
2499 mutex_lock(&pHddCtx->sap_lock);
2500 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2501 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002502 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002503 {
2504 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2505
2506 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2507
2508 if (!VOS_IS_STATUS_SUCCESS(status))
2509 {
2510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002511 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 VOS_ASSERT(0);
2513 }
2514 }
2515 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2516 }
2517 mutex_unlock(&pHddCtx->sap_lock);
2518
2519 if(status != VOS_STATUS_SUCCESS)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002522 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 return -EINVAL;
2524 }
2525
Jeff Johnson4416a782013-03-25 14:17:50 -07002526 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2528 ==eHAL_STATUS_FAILURE)
2529 {
2530 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002531 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 }
2533
Jeff Johnson4416a782013-03-25 14:17:50 -07002534 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002535 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2536 eANI_BOOLEAN_FALSE) )
2537 {
2538 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002539 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002540 }
2541
2542 // Reset WNI_CFG_PROBE_RSP Flags
2543 wlan_hdd_reset_prob_rspies(pAdapter);
2544
2545 pAdapter->sessionCtx.ap.beacon = NULL;
2546 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002547#ifdef WLAN_FEATURE_P2P_DEBUG
2548 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2549 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2550 {
2551 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2552 "GO got removed");
2553 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2554 }
2555#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002556 }
2557 EXIT();
2558 return status;
2559}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002560
2561#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2562
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302563static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2564 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002565 struct cfg80211_ap_settings *params)
2566{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302567 hdd_adapter_t *pAdapter;
2568 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302569 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002570
2571 ENTER();
2572
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302573 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002574 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302576 "%s: Device is Null", __func__);
2577 return -ENODEV;
2578 }
2579
2580 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2581 if (NULL == pAdapter)
2582 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302584 "%s: HDD adapter is Null", __func__);
2585 return -ENODEV;
2586 }
2587
2588 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2589 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302591 "%s: HDD adapter magic is invalid", __func__);
2592 return -ENODEV;
2593 }
2594
2595 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302596 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302597
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302598 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302599 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2601 "%s: HDD context is not valid", __func__);
2602 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302603 }
2604
2605 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2606 __func__, pAdapter->device_mode);
2607
2608 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002609 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002610 )
2611 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302612 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002613
2614 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302615
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002616 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302617 {
2618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2619 FL("already beacon info added to session(%d)"),
2620 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002621 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302622 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002623
2624 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2625
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302626 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002627 {
2628 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302629 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002630 return -EINVAL;
2631 }
2632 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002634 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2635#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2636 params->channel, params->channel_type);
2637#else
2638 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2639#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002640#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002641 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2642 params->ssid_len, params->hidden_ssid);
2643 }
2644
2645 EXIT();
2646 return status;
2647}
2648
2649
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302650static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002651 struct net_device *dev,
2652 struct cfg80211_beacon_data *params)
2653{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302655 hdd_context_t *pHddCtx;
2656 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002657
2658 ENTER();
2659
Arif Hussain6d2a3322013-11-17 19:50:10 -08002660 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002661 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302662
2663 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2664 status = wlan_hdd_validate_context(pHddCtx);
2665
2666 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002667 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2669 "%s: HDD context is not valid", __func__);
2670 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002671 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002672
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302673 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002674 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302675 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002676 {
2677 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302678
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002679 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302680
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002681 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302682 {
2683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2684 FL("session(%d) beacon data points to NULL"),
2685 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002686 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302687 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002688
2689 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2690
2691 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302692 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002693 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002694 return -EINVAL;
2695 }
2696
2697 pAdapter->sessionCtx.ap.beacon = new;
2698
2699 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2700 }
2701
2702 EXIT();
2703 return status;
2704}
2705
2706#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2707
Jeff Johnson295189b2012-06-20 16:38:30 -07002708
2709static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2710 struct net_device *dev,
2711 struct bss_parameters *params)
2712{
2713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2714
2715 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302716
Arif Hussain6d2a3322013-11-17 19:50:10 -08002717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002718 __func__,pAdapter->device_mode);
2719
2720 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002721 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302722 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002723 {
2724 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2725 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302726 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002727 {
2728 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002730 }
2731
2732 EXIT();
2733 return 0;
2734}
2735
Kiet Lam10841362013-11-01 11:36:50 +05302736/* FUNCTION: wlan_hdd_change_country_code_cd
2737* to wait for contry code completion
2738*/
2739void* wlan_hdd_change_country_code_cb(void *pAdapter)
2740{
2741 hdd_adapter_t *call_back_pAdapter = pAdapter;
2742 complete(&call_back_pAdapter->change_country_code);
2743 return NULL;
2744}
2745
Jeff Johnson295189b2012-06-20 16:38:30 -07002746/*
2747 * FUNCTION: wlan_hdd_cfg80211_change_iface
2748 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2749 */
2750int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2751 struct net_device *ndev,
2752 enum nl80211_iftype type,
2753 u32 *flags,
2754 struct vif_params *params
2755 )
2756{
2757 struct wireless_dev *wdev;
2758 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002759 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002760 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002761 tCsrRoamProfile *pRoamProfile = NULL;
2762 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302763 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002764 eMib_dot11DesiredBssType connectedBssType;
2765 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302766 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002767
2768 ENTER();
2769
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002770 if (!pAdapter)
2771 {
2772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "%s: Adapter context is null", __func__);
2774 return VOS_STATUS_E_FAILURE;
2775 }
2776
2777 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2778 if (!pHddCtx)
2779 {
2780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: HDD context is null", __func__);
2782 return VOS_STATUS_E_FAILURE;
2783 }
2784
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302785 status = wlan_hdd_validate_context(pHddCtx);
2786
2787 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002788 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2790 "%s: HDD context is not valid", __func__);
2791 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002792 }
2793
2794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2795 __func__, pAdapter->device_mode);
2796
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302797 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002798 wdev = ndev->ieee80211_ptr;
2799
2800#ifdef WLAN_BTAMP_FEATURE
2801 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2802 (NL80211_IFTYPE_ADHOC == type)||
2803 (NL80211_IFTYPE_AP == type)||
2804 (NL80211_IFTYPE_P2P_GO == type))
2805 {
2806 pHddCtx->isAmpAllowed = VOS_FALSE;
2807 // stop AMP traffic
2808 status = WLANBAP_StopAmp();
2809 if(VOS_STATUS_SUCCESS != status )
2810 {
2811 pHddCtx->isAmpAllowed = VOS_TRUE;
2812 hddLog(VOS_TRACE_LEVEL_FATAL,
2813 "%s: Failed to stop AMP", __func__);
2814 return -EINVAL;
2815 }
2816 }
2817#endif //WLAN_BTAMP_FEATURE
2818 /* Reset the current device mode bit mask*/
2819 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2820
2821 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002823 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002824 )
2825 {
2826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002827 if (!pWextState)
2828 {
2829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2830 "%s: pWextState is null", __func__);
2831 return VOS_STATUS_E_FAILURE;
2832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002833 pRoamProfile = &pWextState->roamProfile;
2834 LastBSSType = pRoamProfile->BSSType;
2835
2836 switch (type)
2837 {
2838 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002839 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 hddLog(VOS_TRACE_LEVEL_INFO,
2841 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2842 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002843#ifdef WLAN_FEATURE_11AC
2844 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2845 {
2846 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2847 }
2848#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302849 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002850 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002851 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002852 //Check for sub-string p2p to confirm its a p2p interface
2853 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302854 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002855 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2856 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2857 }
2858 else
2859 {
2860 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002861 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002862 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302863#ifdef FEATURE_WLAN_TDLS
2864 /* The open adapter for the p2p shall skip initializations in
2865 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2866 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2867 * tdls_init when the change_iface sets the device mode to
2868 * WLAN_HDD_P2P_CLIENT.
2869 */
2870
2871 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2872 {
2873 if (0 != wlan_hdd_tdls_init (pAdapter))
2874 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302875 hddLog(VOS_TRACE_LEVEL_ERROR,
2876 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302877 return -EINVAL;
2878 }
2879 }
2880#endif
2881
Jeff Johnson295189b2012-06-20 16:38:30 -07002882 break;
2883 case NL80211_IFTYPE_ADHOC:
2884 hddLog(VOS_TRACE_LEVEL_INFO,
2885 "%s: setting interface Type to ADHOC", __func__);
2886 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2887 pRoamProfile->phyMode =
2888 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002889 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002890 wdev->iftype = type;
2891 break;
2892
2893 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002894 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002895 {
2896 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2897 "%s: setting interface Type to %s", __func__,
2898 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2899
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002900 //Cancel any remain on channel for GO mode
2901 if (NL80211_IFTYPE_P2P_GO == type)
2902 {
2903 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2904 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002905 if (NL80211_IFTYPE_AP == type)
2906 {
2907 /* As Loading WLAN Driver one interface being created for p2p device
2908 * address. This will take one HW STA and the max number of clients
2909 * that can connect to softAP will be reduced by one. so while changing
2910 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2911 * interface as it is not required in SoftAP mode.
2912 */
2913
2914 // Get P2P Adapter
2915 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2916
2917 if (pP2pAdapter)
2918 {
2919 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2920 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2921 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2922 }
2923 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302924#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002925
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302926 /* A Mutex Lock is introduced while changing the mode to
2927 * protect the concurrent access for the Adapters by TDLS
2928 * module.
2929 */
2930 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2931 {
2932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2933 "%s: unable to lock list", __func__);
2934 return -EINVAL;
2935 }
2936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002937 //De-init the adapter.
2938 hdd_stop_adapter( pHddCtx, pAdapter );
2939 hdd_deinit_adapter( pHddCtx, pAdapter );
2940 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002941 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2942 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302943#ifdef FEATURE_WLAN_TDLS
2944 mutex_unlock(&pHddCtx->tdls_lock);
2945#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002946
2947 //Disable BMPS and IMPS if enabled
2948 //before starting Go
2949 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302951 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002952 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2953 {
2954 //Fail to Exit BMPS
2955 VOS_ASSERT(0);
2956 }
2957 }
2958
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002959 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2960 (pConfig->apRandomBssidEnabled))
2961 {
2962 /* To meet Android requirements create a randomized
2963 MAC address of the form 02:1A:11:Fx:xx:xx */
2964 get_random_bytes(&ndev->dev_addr[3], 3);
2965 ndev->dev_addr[0] = 0x02;
2966 ndev->dev_addr[1] = 0x1A;
2967 ndev->dev_addr[2] = 0x11;
2968 ndev->dev_addr[3] |= 0xF0;
2969 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2970 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002971 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2972 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002973 }
2974
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 hdd_set_ap_ops( pAdapter->dev );
2976
Kiet Lam10841362013-11-01 11:36:50 +05302977 /* This is for only SAP mode where users can
2978 * control country through ini.
2979 * P2P GO follows station country code
2980 * acquired during the STA scanning. */
2981 if((NL80211_IFTYPE_AP == type) &&
2982 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
2983 {
2984 int status = 0;
2985 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
2986 "%s: setting country code from INI ", __func__);
2987 init_completion(&pAdapter->change_country_code);
2988 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2989 (void *)(tSmeChangeCountryCallback)
2990 wlan_hdd_change_country_code_cb,
2991 pConfig->apCntryCode, pAdapter,
2992 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05302993 eSIR_FALSE,
2994 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05302995 if (eHAL_STATUS_SUCCESS == status)
2996 {
2997 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302998 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05302999 &pAdapter->change_country_code,
3000 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303001 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303002 {
3003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303004 FL("SME Timed out while setting country code %ld"),
3005 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003006
3007 if (pHddCtx->isLogpInProgress)
3008 {
3009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3010 "%s: LOGP in Progress. Ignore!!!", __func__);
3011 return -EAGAIN;
3012 }
Kiet Lam10841362013-11-01 11:36:50 +05303013 }
3014 }
3015 else
3016 {
3017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003018 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303019 return -EINVAL;
3020 }
3021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003022 status = hdd_init_ap_mode(pAdapter);
3023 if(status != VOS_STATUS_SUCCESS)
3024 {
3025 hddLog(VOS_TRACE_LEVEL_FATAL,
3026 "%s: Error initializing the ap mode", __func__);
3027 return -EINVAL;
3028 }
3029 hdd_set_conparam(1);
3030
Jeff Johnson295189b2012-06-20 16:38:30 -07003031 /*interface type changed update in wiphy structure*/
3032 if(wdev)
3033 {
3034 wdev->iftype = type;
3035 pHddCtx->change_iface = type;
3036 }
3037 else
3038 {
3039 hddLog(VOS_TRACE_LEVEL_ERROR,
3040 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3041 return -EINVAL;
3042 }
3043 goto done;
3044 }
3045
3046 default:
3047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3048 __func__);
3049 return -EOPNOTSUPP;
3050 }
3051 }
3052 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003053 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003054 )
3055 {
3056 switch(type)
3057 {
3058 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003059 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003060 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303061#ifdef FEATURE_WLAN_TDLS
3062
3063 /* A Mutex Lock is introduced while changing the mode to
3064 * protect the concurrent access for the Adapters by TDLS
3065 * module.
3066 */
3067 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
3068 {
3069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3070 "%s: unable to lock list", __func__);
3071 return -EINVAL;
3072 }
3073#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003074 hdd_stop_adapter( pHddCtx, pAdapter );
3075 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003077 //Check for sub-string p2p to confirm its a p2p interface
3078 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003079 {
3080 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3081 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3082 }
3083 else
3084 {
3085 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003086 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 hdd_set_conparam(0);
3089 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003090 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3091 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303092#ifdef FEATURE_WLAN_TDLS
3093 mutex_unlock(&pHddCtx->tdls_lock);
3094#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303095 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 if( VOS_STATUS_SUCCESS != status )
3097 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003098 /* In case of JB, for P2P-GO, only change interface will be called,
3099 * This is the right place to enable back bmps_imps()
3100 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303101 if (pHddCtx->hdd_wlan_suspended)
3102 {
3103 hdd_set_pwrparams(pHddCtx);
3104 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003105 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003106 goto done;
3107 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003110 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3111 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003112 goto done;
3113 default:
3114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3115 __func__);
3116 return -EOPNOTSUPP;
3117
3118 }
3119
3120 }
3121 else
3122 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303123 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3124 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003125 return -EOPNOTSUPP;
3126 }
3127
3128
3129 if(pRoamProfile)
3130 {
3131 if ( LastBSSType != pRoamProfile->BSSType )
3132 {
3133 /*interface type changed update in wiphy structure*/
3134 wdev->iftype = type;
3135
3136 /*the BSS mode changed, We need to issue disconnect
3137 if connected or in IBSS disconnect state*/
3138 if ( hdd_connGetConnectedBssType(
3139 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3140 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3141 {
3142 /*need to issue a disconnect to CSR.*/
3143 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3144 if( eHAL_STATUS_SUCCESS ==
3145 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3146 pAdapter->sessionId,
3147 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3148 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303149 ret = wait_for_completion_interruptible_timeout(
3150 &pAdapter->disconnect_comp_var,
3151 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3152 if (ret <= 0)
3153 {
3154 hddLog(VOS_TRACE_LEVEL_ERROR,
3155 FL("wait on disconnect_comp_var failed %ld"), ret);
3156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 }
3158 }
3159 }
3160 }
3161
3162done:
3163 /*set bitmask based on updated value*/
3164 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003165
3166 /* Only STA mode support TM now
3167 * all other mode, TM feature should be disabled */
3168 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3169 (~VOS_STA & pHddCtx->concurrency_mode) )
3170 {
3171 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3172 }
3173
Jeff Johnson295189b2012-06-20 16:38:30 -07003174#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303175 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003176 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3177 {
3178 //we are ok to do AMP
3179 pHddCtx->isAmpAllowed = VOS_TRUE;
3180 }
3181#endif //WLAN_BTAMP_FEATURE
3182 EXIT();
3183 return 0;
3184}
3185
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003186#ifdef FEATURE_WLAN_TDLS
3187static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3188 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3189{
3190 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3191 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3192 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003193 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303194 long ret;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003195
3196 ENTER();
3197
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303198 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003199 {
3200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3201 "Invalid arguments");
3202 return -EINVAL;
3203 }
Hoonki Lee27511902013-03-14 18:19:06 -07003204
3205 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3206 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3207 {
3208 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3209 "%s: TDLS mode is disabled OR not enabled in FW."
3210 MAC_ADDRESS_STR " Request declined.",
3211 __func__, MAC_ADDR_ARRAY(mac));
3212 return -ENOTSUPP;
3213 }
3214
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003215 if (pHddCtx->isLogpInProgress)
3216 {
3217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3218 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003219 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003220 return -EBUSY;
3221 }
3222
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303223 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003224
3225 if ( NULL == pTdlsPeer ) {
3226 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3227 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3228 __func__, MAC_ADDR_ARRAY(mac), update);
3229 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003230 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003231
3232 /* in add station, we accept existing valid staId if there is */
3233 if ((0 == update) &&
3234 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3235 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003236 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003237 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003238 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003239 " link_status %d. staId %d. add station ignored.",
3240 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3241 return 0;
3242 }
3243 /* in change station, we accept only when staId is valid */
3244 if ((1 == update) &&
3245 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3246 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3247 {
3248 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3249 "%s: " MAC_ADDRESS_STR
3250 " link status %d. staId %d. change station %s.",
3251 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3252 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3253 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003254 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003255
3256 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303257 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003258 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3260 "%s: " MAC_ADDRESS_STR
3261 " TDLS setup is ongoing. Request declined.",
3262 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003263 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003264 }
3265
3266 /* first to check if we reached to maximum supported TDLS peer.
3267 TODO: for now, return -EPERM looks working fine,
3268 but need to check if any other errno fit into this category.*/
3269 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
3270 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3272 "%s: " MAC_ADDRESS_STR
3273 " TDLS Max peer already connected. Request declined.",
3274 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003275 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003276 }
3277 else
3278 {
3279 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303280 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003281 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003282 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3284 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3285 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003286 return -EPERM;
3287 }
3288 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003289 if (0 == update)
3290 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003291
Jeff Johnsond75fe012013-04-06 10:53:06 -07003292 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303293 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003294 {
3295 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3296 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003297 if(StaParams->htcap_present)
3298 {
3299 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3300 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3301 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3302 "ht_capa->extended_capabilities: %0x",
3303 StaParams->HTCap.extendedHtCapInfo);
3304 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003305 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3306 "params->capability: %0x",StaParams->capability);
3307 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003308 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003309 if(StaParams->vhtcap_present)
3310 {
3311 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3312 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3313 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3314 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3315 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003316 {
3317 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003319 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3320 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3321 "[%d]: %x ", i, StaParams->supported_rates[i]);
3322 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003323 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303324 else if ((1 == update) && (NULL == StaParams))
3325 {
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s : update is true, but staParams is NULL. Error!", __func__);
3328 return -EPERM;
3329 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003330
3331 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3332
3333 if (!update)
3334 {
3335 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3336 pAdapter->sessionId, mac);
3337 }
3338 else
3339 {
3340 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3341 pAdapter->sessionId, mac, StaParams);
3342 }
3343
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303344 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003345 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3346
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303347 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303350 "%s: timeout waiting for tdls add station indication %ld",
3351 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003352 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003353 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303354
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003355 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3356 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003358 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003359 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003360 }
3361
3362 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003363
3364error:
3365 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3366 return -EPERM;
3367
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003368}
3369#endif
3370
Jeff Johnson295189b2012-06-20 16:38:30 -07003371static int wlan_hdd_change_station(struct wiphy *wiphy,
3372 struct net_device *dev,
3373 u8 *mac,
3374 struct station_parameters *params)
3375{
3376 VOS_STATUS status = VOS_STATUS_SUCCESS;
3377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303378 hdd_context_t *pHddCtx;
3379 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003381#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003382 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003383 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303384 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003385#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003386 ENTER();
3387
Gopichand Nakkala29149562013-05-10 21:43:41 +05303388 if ((NULL == pAdapter))
3389 {
3390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3391 "invalid adapter ");
3392 return -EINVAL;
3393 }
3394
3395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3396 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3397
3398 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3399 {
3400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3401 "invalid HDD state or HDD station context");
3402 return -EINVAL;
3403 }
3404
3405 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003406 {
3407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3408 "%s:LOGP in Progress. Ignore!!!", __func__);
3409 return -EAGAIN;
3410 }
3411
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3413
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003414 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3415 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003416 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003417 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303419 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003420 WLANTL_STA_AUTHENTICATED);
3421
Gopichand Nakkala29149562013-05-10 21:43:41 +05303422 if (status != VOS_STATUS_SUCCESS)
3423 {
3424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3425 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3426 return -EINVAL;
3427 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003428 }
3429 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003430 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3431 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303432#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003433 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3434 StaParams.capability = params->capability;
3435 StaParams.uapsd_queues = params->uapsd_queues;
3436 StaParams.max_sp = params->max_sp;
3437
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303438 /* Convert (first channel , number of channels) tuple to
3439 * the total list of channels. This goes with the assumption
3440 * that if the first channel is < 14, then the next channels
3441 * are an incremental of 1 else an incremental of 4 till the number
3442 * of channels.
3443 */
3444 if (0 != params->supported_channels_len) {
3445 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3446 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3447 {
3448 int wifi_chan_index;
3449 StaParams.supported_channels[j] = params->supported_channels[i];
3450 wifi_chan_index =
3451 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3452 no_of_channels = params->supported_channels[i+1];
3453 for(k=1; k <= no_of_channels; k++)
3454 {
3455 StaParams.supported_channels[j+1] =
3456 StaParams.supported_channels[j] + wifi_chan_index;
3457 j+=1;
3458 }
3459 }
3460 StaParams.supported_channels_len = j;
3461 }
3462 vos_mem_copy(StaParams.supported_oper_classes,
3463 params->supported_oper_classes,
3464 params->supported_oper_classes_len);
3465 StaParams.supported_oper_classes_len =
3466 params->supported_oper_classes_len;
3467
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003468 if (0 != params->ext_capab_len)
3469 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3470 sizeof(StaParams.extn_capability));
3471
3472 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003473 {
3474 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003475 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003476 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003477
3478 StaParams.supported_rates_len = params->supported_rates_len;
3479
3480 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3481 * The supported_rates array , for all the structures propogating till Add Sta
3482 * to the firmware has to be modified , if the supplicant (ieee80211) is
3483 * modified to send more rates.
3484 */
3485
3486 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3487 */
3488 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3489 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3490
3491 if (0 != StaParams.supported_rates_len) {
3492 int i = 0;
3493 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3494 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003496 "Supported Rates with Length %d", StaParams.supported_rates_len);
3497 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003499 "[%d]: %0x", i, StaParams.supported_rates[i]);
3500 }
3501
3502 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003503 {
3504 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003505 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003506 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003507
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003508 if (0 != params->ext_capab_len ) {
3509 /*Define A Macro : TODO Sunil*/
3510 if ((1<<4) & StaParams.extn_capability[3]) {
3511 isBufSta = 1;
3512 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303513 /* TDLS Channel Switching Support */
3514 if ((1<<6) & StaParams.extn_capability[3]) {
3515 isOffChannelSupported = 1;
3516 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003517 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303518 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3519 &StaParams, isBufSta,
3520 isOffChannelSupported);
3521
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303522 if (VOS_STATUS_SUCCESS != status) {
3523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3524 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3525 return -EINVAL;
3526 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003527 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3528
3529 if (VOS_STATUS_SUCCESS != status) {
3530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3531 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3532 return -EINVAL;
3533 }
3534 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003535#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303536 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003537 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003538 return status;
3539}
3540
3541/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003542 * FUNCTION: wlan_hdd_cfg80211_add_key
3543 * This function is used to initialize the key information
3544 */
3545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003546static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003547 struct net_device *ndev,
3548 u8 key_index, bool pairwise,
3549 const u8 *mac_addr,
3550 struct key_params *params
3551 )
3552#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003553static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003554 struct net_device *ndev,
3555 u8 key_index, const u8 *mac_addr,
3556 struct key_params *params
3557 )
3558#endif
3559{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003561 tCsrRoamSetKey setKey;
3562 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303563 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003564 v_U32_t roamId= 0xFF;
3565 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003566 hdd_hostapd_state_t *pHostapdState;
3567 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003568 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303569 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003570
3571 ENTER();
3572
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303573 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3574 status = wlan_hdd_validate_context(pHddCtx);
3575
3576 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003577 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "%s: HDD context is not valid", __func__);
3580 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003581 }
3582
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3584 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003585
3586 if (CSR_MAX_NUM_KEY <= key_index)
3587 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 key_index);
3590
3591 return -EINVAL;
3592 }
3593
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003594 if (CSR_MAX_KEY_LEN < params->key_len)
3595 {
3596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3597 params->key_len);
3598
3599 return -EINVAL;
3600 }
3601
3602 hddLog(VOS_TRACE_LEVEL_INFO,
3603 "%s: called with key index = %d & key length %d",
3604 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003605
3606 /*extract key idx, key len and key*/
3607 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3608 setKey.keyId = key_index;
3609 setKey.keyLength = params->key_len;
3610 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3611
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003612 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003613 {
3614 case WLAN_CIPHER_SUITE_WEP40:
3615 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3616 break;
3617
3618 case WLAN_CIPHER_SUITE_WEP104:
3619 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3620 break;
3621
3622 case WLAN_CIPHER_SUITE_TKIP:
3623 {
3624 u8 *pKey = &setKey.Key[0];
3625 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3626
3627 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3628
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003629 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003630
3631 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003632 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 |--------------|----------|----------|
3634 <---16bytes---><--8bytes--><--8bytes-->
3635
3636 */
3637 /*Sme expects the 32 bytes key to be in the below order
3638
3639 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003640 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 |--------------|----------|----------|
3642 <---16bytes---><--8bytes--><--8bytes-->
3643 */
3644 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003645 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003646
3647 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003648 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003649
3650 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003651 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003652
3653
3654 break;
3655 }
3656
3657 case WLAN_CIPHER_SUITE_CCMP:
3658 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3659 break;
3660
3661#ifdef FEATURE_WLAN_WAPI
3662 case WLAN_CIPHER_SUITE_SMS4:
3663 {
3664 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3665 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3666 params->key, params->key_len);
3667 return 0;
3668 }
3669#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003670
Jeff Johnson295189b2012-06-20 16:38:30 -07003671#ifdef FEATURE_WLAN_CCX
3672 case WLAN_CIPHER_SUITE_KRK:
3673 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3674 break;
3675#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003676
3677#ifdef WLAN_FEATURE_11W
3678 case WLAN_CIPHER_SUITE_AES_CMAC:
3679 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003680 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003681#endif
3682
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 __func__, params->cipher);
3686 return -EOPNOTSUPP;
3687 }
3688
3689 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3690 __func__, setKey.encType);
3691
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003692 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3694 (!pairwise)
3695#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003696 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003697#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003698 )
3699 {
3700 /* set group key*/
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3702 "%s- %d: setting Broadcast key",
3703 __func__, __LINE__);
3704 setKey.keyDirection = eSIR_RX_ONLY;
3705 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3706 }
3707 else
3708 {
3709 /* set pairwise key*/
3710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3711 "%s- %d: setting pairwise key",
3712 __func__, __LINE__);
3713 setKey.keyDirection = eSIR_TX_RX;
3714 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3715 }
3716 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3717 {
3718 setKey.keyDirection = eSIR_TX_RX;
3719 /*Set the group key*/
3720 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3721 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003722
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003723 if ( 0 != status )
3724 {
3725 hddLog(VOS_TRACE_LEVEL_ERROR,
3726 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3727 return -EINVAL;
3728 }
3729 /*Save the keys here and call sme_RoamSetKey for setting
3730 the PTK after peer joins the IBSS network*/
3731 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3732 &setKey, sizeof(tCsrRoamSetKey));
3733 return status;
3734 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303735 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3736 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3737 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003738 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003739 if( pHostapdState->bssState == BSS_START )
3740 {
c_hpothu7c55da62014-01-23 18:34:02 +05303741 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3742 vos_status = wlan_hdd_check_ula_done(pAdapter);
3743
3744 if ( vos_status != VOS_STATUS_SUCCESS )
3745 {
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3747 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3748 __LINE__, vos_status );
3749
3750 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3751
3752 return -EINVAL;
3753 }
3754
Jeff Johnson295189b2012-06-20 16:38:30 -07003755 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3756
3757 if ( status != eHAL_STATUS_SUCCESS )
3758 {
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3760 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3761 __LINE__, status );
3762 }
3763 }
3764
3765 /* Saving WEP keys */
3766 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3767 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3768 {
3769 //Save the wep key in ap context. Issue setkey after the BSS is started.
3770 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3771 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3772 }
3773 else
3774 {
3775 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003776 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003777 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3778 }
3779 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003780 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3781 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003782 {
3783 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3785
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3787 if (!pairwise)
3788#else
3789 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3790#endif
3791 {
3792 /* set group key*/
3793 if (pHddStaCtx->roam_info.deferKeyComplete)
3794 {
3795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3796 "%s- %d: Perform Set key Complete",
3797 __func__, __LINE__);
3798 hdd_PerformRoamSetKeyComplete(pAdapter);
3799 }
3800 }
3801
Jeff Johnson295189b2012-06-20 16:38:30 -07003802 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3803
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003804 pWextState->roamProfile.Keys.defaultIndex = key_index;
3805
3806
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003807 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003808 params->key, params->key_len);
3809
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303810
Jeff Johnson295189b2012-06-20 16:38:30 -07003811 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3812
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303813 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003814 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303815 __func__, setKey.peerMac[0], setKey.peerMac[1],
3816 setKey.peerMac[2], setKey.peerMac[3],
3817 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003818 setKey.keyDirection);
3819
3820 vos_status = wlan_hdd_check_ula_done(pAdapter);
3821
3822 if ( vos_status != VOS_STATUS_SUCCESS )
3823 {
3824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3825 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3826 __LINE__, vos_status );
3827
3828 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3829
3830 return -EINVAL;
3831
3832 }
3833
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003834#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303835 /* The supplicant may attempt to set the PTK once pre-authentication
3836 is done. Save the key in the UMAC and include it in the ADD BSS
3837 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003838 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303839 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003840 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303841 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3842 "%s: Update PreAuth Key success", __func__);
3843 return 0;
3844 }
3845 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3846 {
3847 hddLog(VOS_TRACE_LEVEL_ERROR,
3848 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303849 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003850 }
3851#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003852
3853 /* issue set key request to SME*/
3854 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3855 pAdapter->sessionId, &setKey, &roamId );
3856
3857 if ( 0 != status )
3858 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303859 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003860 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3861 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3862 return -EINVAL;
3863 }
3864
3865
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303866 /* in case of IBSS as there was no information available about WEP keys during
3867 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003868 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303869 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3870 !( ( IW_AUTH_KEY_MGMT_802_1X
3871 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003872 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3873 )
3874 &&
3875 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3876 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3877 )
3878 )
3879 {
3880 setKey.keyDirection = eSIR_RX_ONLY;
3881 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3882
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303883 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003884 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303885 __func__, setKey.peerMac[0], setKey.peerMac[1],
3886 setKey.peerMac[2], setKey.peerMac[3],
3887 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 setKey.keyDirection);
3889
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303890 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003891 pAdapter->sessionId, &setKey, &roamId );
3892
3893 if ( 0 != status )
3894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303895 hddLog(VOS_TRACE_LEVEL_ERROR,
3896 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003897 __func__, status);
3898 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3899 return -EINVAL;
3900 }
3901 }
3902 }
3903
3904 return 0;
3905}
3906
3907/*
3908 * FUNCTION: wlan_hdd_cfg80211_get_key
3909 * This function is used to get the key information
3910 */
3911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303912static int wlan_hdd_cfg80211_get_key(
3913 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303915 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 const u8 *mac_addr, void *cookie,
3917 void (*callback)(void *cookie, struct key_params*)
3918 )
3919#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303920static int wlan_hdd_cfg80211_get_key(
3921 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 struct net_device *ndev,
3923 u8 key_index, const u8 *mac_addr, void *cookie,
3924 void (*callback)(void *cookie, struct key_params*)
3925 )
3926#endif
3927{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303928 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003929 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3930 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3931 struct key_params params;
3932
3933 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303934
Arif Hussain6d2a3322013-11-17 19:50:10 -08003935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003936 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303937
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 memset(&params, 0, sizeof(params));
3939
3940 if (CSR_MAX_NUM_KEY <= key_index)
3941 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003943 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003945
3946 switch(pRoamProfile->EncryptionType.encryptionType[0])
3947 {
3948 case eCSR_ENCRYPT_TYPE_NONE:
3949 params.cipher = IW_AUTH_CIPHER_NONE;
3950 break;
3951
3952 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3953 case eCSR_ENCRYPT_TYPE_WEP40:
3954 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3955 break;
3956
3957 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3958 case eCSR_ENCRYPT_TYPE_WEP104:
3959 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3960 break;
3961
3962 case eCSR_ENCRYPT_TYPE_TKIP:
3963 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3964 break;
3965
3966 case eCSR_ENCRYPT_TYPE_AES:
3967 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3968 break;
3969
3970 default:
3971 params.cipher = IW_AUTH_CIPHER_NONE;
3972 break;
3973 }
3974
3975 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3976 params.seq_len = 0;
3977 params.seq = NULL;
3978 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3979 callback(cookie, &params);
3980 return 0;
3981}
3982
3983/*
3984 * FUNCTION: wlan_hdd_cfg80211_del_key
3985 * This function is used to delete the key information
3986 */
3987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303988static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003989 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303990 u8 key_index,
3991 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003992 const u8 *mac_addr
3993 )
3994#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303995static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003996 struct net_device *ndev,
3997 u8 key_index,
3998 const u8 *mac_addr
3999 )
4000#endif
4001{
4002 int status = 0;
4003
4004 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304005 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004006 //it is observed that this is invalidating peer
4007 //key index whenever re-key is done. This is affecting data link.
4008 //It should be ok to ignore del_key.
4009#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4011 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004012 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4013 tCsrRoamSetKey setKey;
4014 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304015
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 ENTER();
4017
4018 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4019 __func__,pAdapter->device_mode);
4020
4021 if (CSR_MAX_NUM_KEY <= key_index)
4022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 key_index);
4025
4026 return -EINVAL;
4027 }
4028
4029 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4030 setKey.keyId = key_index;
4031
4032 if (mac_addr)
4033 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4034 else
4035 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4036
4037 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4038
4039 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004040 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041 )
4042 {
4043
4044 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004045 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4046 if( pHostapdState->bssState == BSS_START)
4047 {
4048 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304049
Jeff Johnson295189b2012-06-20 16:38:30 -07004050 if ( status != eHAL_STATUS_SUCCESS )
4051 {
4052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4053 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4054 __LINE__, status );
4055 }
4056 }
4057 }
4058 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304059 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004060 )
4061 {
4062 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4063
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304064 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4065
4066 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004067 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304068 __func__, setKey.peerMac[0], setKey.peerMac[1],
4069 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 if(pAdapter->sessionCtx.station.conn_info.connState ==
4072 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304076
Jeff Johnson295189b2012-06-20 16:38:30 -07004077 if ( 0 != status )
4078 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304079 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004080 "%s: sme_RoamSetKey failure, returned %d",
4081 __func__, status);
4082 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4083 return -EINVAL;
4084 }
4085 }
4086 }
4087#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004088 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 return status;
4090}
4091
4092/*
4093 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4094 * This function is used to set the default tx key index
4095 */
4096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4097static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4098 struct net_device *ndev,
4099 u8 key_index,
4100 bool unicast, bool multicast)
4101#else
4102static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4103 struct net_device *ndev,
4104 u8 key_index)
4105#endif
4106{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304108 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304109 hdd_wext_state_t *pWextState;
4110 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304111 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004112
4113 ENTER();
4114
Gopichand Nakkala29149562013-05-10 21:43:41 +05304115 if ((NULL == pAdapter))
4116 {
4117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4118 "invalid adapter");
4119 return -EINVAL;
4120 }
4121
4122 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4123 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4124
4125 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4126 {
4127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4128 "invalid Wext state or HDD context");
4129 return -EINVAL;
4130 }
4131
Arif Hussain6d2a3322013-11-17 19:50:10 -08004132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304134
Jeff Johnson295189b2012-06-20 16:38:30 -07004135 if (CSR_MAX_NUM_KEY <= key_index)
4136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004138 key_index);
4139
4140 return -EINVAL;
4141 }
4142
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4144 status = wlan_hdd_validate_context(pHddCtx);
4145
4146 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004147 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4149 "%s: HDD context is not valid", __func__);
4150 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004151 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304152
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004154 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304155 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304157 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004158 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304159 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004160 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304162 {
4163 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004164 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304165
Jeff Johnson295189b2012-06-20 16:38:30 -07004166 tCsrRoamSetKey setKey;
4167 v_U32_t roamId= 0xFF;
4168 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169
4170 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172
Jeff Johnson295189b2012-06-20 16:38:30 -07004173 Keys->defaultIndex = (u8)key_index;
4174 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4175 setKey.keyId = key_index;
4176 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304177
4178 vos_mem_copy(&setKey.Key[0],
4179 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181
Gopichand Nakkala29149562013-05-10 21:43:41 +05304182 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304183
4184 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 &pHddStaCtx->conn_info.bssId[0],
4186 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304187
Gopichand Nakkala29149562013-05-10 21:43:41 +05304188 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4189 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4190 eCSR_ENCRYPT_TYPE_WEP104)
4191 {
4192 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4193 even though ap is configured for WEP-40 encryption. In this canse the key length
4194 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4195 type(104) and switching encryption type to 40*/
4196 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4197 eCSR_ENCRYPT_TYPE_WEP40;
4198 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4199 eCSR_ENCRYPT_TYPE_WEP40;
4200 }
4201
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304202 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004203 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304204
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304206 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304208
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 if ( 0 != status )
4210 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304211 hddLog(VOS_TRACE_LEVEL_ERROR,
4212 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 status);
4214 return -EINVAL;
4215 }
4216 }
4217 }
4218
4219 /* In SoftAp mode setting key direction for default mode */
4220 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4221 {
4222 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4223 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4224 (eCSR_ENCRYPT_TYPE_AES !=
4225 pWextState->roamProfile.EncryptionType.encryptionType[0])
4226 )
4227 {
4228 /* Saving key direction for default key index to TX default */
4229 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4230 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4231 }
4232 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304233
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 return status;
4235}
4236
Jeff Johnson295189b2012-06-20 16:38:30 -07004237/*
4238 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4239 * This function is used to inform the BSS details to nl80211 interface.
4240 */
4241static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4242 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4243{
4244 struct net_device *dev = pAdapter->dev;
4245 struct wireless_dev *wdev = dev->ieee80211_ptr;
4246 struct wiphy *wiphy = wdev->wiphy;
4247 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4248 int chan_no;
4249 int ie_length;
4250 const char *ie;
4251 unsigned int freq;
4252 struct ieee80211_channel *chan;
4253 int rssi = 0;
4254 struct cfg80211_bss *bss = NULL;
4255
4256 ENTER();
4257
4258 if( NULL == pBssDesc )
4259 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004260 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004261 return bss;
4262 }
4263
4264 chan_no = pBssDesc->channelId;
4265 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4266 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4267
4268 if( NULL == ie )
4269 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 return bss;
4272 }
4273
4274#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4275 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4276 {
4277 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4278 }
4279 else
4280 {
4281 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4282 }
4283#else
4284 freq = ieee80211_channel_to_frequency(chan_no);
4285#endif
4286
4287 chan = __ieee80211_get_channel(wiphy, freq);
4288
4289 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4290 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4291 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4292 if (bss == NULL)
4293 {
4294 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4295
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304296 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4297 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004298 pBssDesc->capabilityInfo,
4299 pBssDesc->beaconInterval, ie, ie_length,
4300 rssi, GFP_KERNEL ));
4301}
4302 else
4303 {
4304 return bss;
4305 }
4306}
4307
4308
4309
4310/*
4311 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4312 * This function is used to inform the BSS details to nl80211 interface.
4313 */
4314struct cfg80211_bss*
4315wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4316 tSirBssDescription *bss_desc
4317 )
4318{
4319 /*
4320 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4321 already exists in bss data base of cfg80211 for that particular BSS ID.
4322 Using cfg80211_inform_bss_frame to update the bss entry instead of
4323 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4324 now there is no possibility to get the mgmt(probe response) frame from PE,
4325 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4326 cfg80211_inform_bss_frame.
4327 */
4328 struct net_device *dev = pAdapter->dev;
4329 struct wireless_dev *wdev = dev->ieee80211_ptr;
4330 struct wiphy *wiphy = wdev->wiphy;
4331 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004332#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4333 qcom_ie_age *qie_age = NULL;
4334 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4335#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004336 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004337#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004338 const char *ie =
4339 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4340 unsigned int freq;
4341 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304342 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004343 struct cfg80211_bss *bss_status = NULL;
4344 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4345 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004346 hdd_context_t *pHddCtx;
4347 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004348#ifdef WLAN_OPEN_SOURCE
4349 struct timespec ts;
4350#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004351
Wilson Yangf80a0542013-10-07 13:02:37 -07004352 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4353 status = wlan_hdd_validate_context(pHddCtx);
4354
4355 /*bss_update is not allowed during wlan driver loading or unloading*/
4356 if (pHddCtx->isLoadUnloadInProgress)
4357 {
4358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4359 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4360 return NULL;
4361 }
4362
4363
4364 if (0 != status)
4365 {
4366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4367 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004368 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004369 }
4370
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304371 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004372 if (!mgmt)
4373 {
4374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4375 "%s: memory allocation failed ", __func__);
4376 return NULL;
4377 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004378
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004380
4381#ifdef WLAN_OPEN_SOURCE
4382 /* Android does not want the timestamp from the frame.
4383 Instead it wants a monotonic increasing value */
4384 get_monotonic_boottime(&ts);
4385 mgmt->u.probe_resp.timestamp =
4386 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4387#else
4388 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004389 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4390 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004391
4392#endif
4393
Jeff Johnson295189b2012-06-20 16:38:30 -07004394 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4395 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004396
4397#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4398 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4399 /* Assuming this is the last IE, copy at the end */
4400 ie_length -=sizeof(qcom_ie_age);
4401 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4402 qie_age->element_id = QCOM_VENDOR_IE_ID;
4403 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4404 qie_age->oui_1 = QCOM_OUI1;
4405 qie_age->oui_2 = QCOM_OUI2;
4406 qie_age->oui_3 = QCOM_OUI3;
4407 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4408 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4409#endif
4410
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304412 if (bss_desc->fProbeRsp)
4413 {
4414 mgmt->frame_control |=
4415 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4416 }
4417 else
4418 {
4419 mgmt->frame_control |=
4420 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004422
4423#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304424 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004425 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4426 {
4427 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4428 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304429 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4431
4432 {
4433 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4434 }
4435 else
4436 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4438 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 kfree(mgmt);
4440 return NULL;
4441 }
4442#else
4443 freq = ieee80211_channel_to_frequency(chan_no);
4444#endif
4445 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004446 /*when the band is changed on the fly using the GUI, three things are done
4447 * 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)
4448 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4449 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4450 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4451 * and discards the channels correponding to previous band and calls back with zero bss results.
4452 * 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
4453 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4454 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4455 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4456 * So drop the bss and continue to next bss.
4457 */
4458 if(chan == NULL)
4459 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004461 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004462 return NULL;
4463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304465 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004466 * */
4467 if (( eConnectionState_Associated ==
4468 pAdapter->sessionCtx.station.conn_info.connState ) &&
4469 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4470 pAdapter->sessionCtx.station.conn_info.bssId,
4471 WNI_CFG_BSSID_LEN)))
4472 {
4473 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4474 rssi = (pAdapter->rssi * 100);
4475 }
4476 else
4477 {
4478 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4479 }
4480
Nirav Shah20ac06f2013-12-12 18:14:06 +05304481 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4482 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4483 chan->center_freq, (int)(rssi/100));
4484
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4486 frame_len, rssi, GFP_KERNEL);
4487 kfree(mgmt);
4488 return bss_status;
4489}
4490
4491/*
4492 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4493 * This function is used to update the BSS data base of CFG8011
4494 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304495struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 tCsrRoamInfo *pRoamInfo
4497 )
4498{
4499 tCsrRoamConnectedProfile roamProfile;
4500 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4501 struct cfg80211_bss *bss = NULL;
4502
4503 ENTER();
4504
4505 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4506 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4507
4508 if (NULL != roamProfile.pBssDesc)
4509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304510 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 &roamProfile);
4512
4513 if (NULL == bss)
4514 {
4515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4516 __func__);
4517 }
4518
4519 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4520 }
4521 else
4522 {
4523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4524 __func__);
4525 }
4526 return bss;
4527}
4528
4529/*
4530 * FUNCTION: wlan_hdd_cfg80211_update_bss
4531 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304532static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4533 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004534 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304535{
Jeff Johnson295189b2012-06-20 16:38:30 -07004536 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4537 tCsrScanResultInfo *pScanResult;
4538 eHalStatus status = 0;
4539 tScanResultHandle pResult;
4540 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004541 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004542
4543 ENTER();
4544
Wilson Yangf80a0542013-10-07 13:02:37 -07004545 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4546
4547 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4550 "%s:LOGP in Progress. Ignore!!!",__func__);
4551 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004552 }
4553
Wilson Yangf80a0542013-10-07 13:02:37 -07004554
4555 /*bss_update is not allowed during wlan driver loading or unloading*/
4556 if (pHddCtx->isLoadUnloadInProgress)
4557 {
4558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4559 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4560 return VOS_STATUS_E_PERM;
4561 }
4562
4563
Jeff Johnson295189b2012-06-20 16:38:30 -07004564 /*
4565 * start getting scan results and populate cgf80211 BSS database
4566 */
4567 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4568
4569 /* no scan results */
4570 if (NULL == pResult)
4571 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304572 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4573 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004574 return status;
4575 }
4576
4577 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4578
4579 while (pScanResult)
4580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304581 /*
4582 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4583 * entry already exists in bss data base of cfg80211 for that
4584 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4585 * bss entry instead of cfg80211_inform_bss, But this call expects
4586 * mgmt packet as input. As of now there is no possibility to get
4587 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004588 * ieee80211_mgmt(probe response) and passing to c
4589 * fg80211_inform_bss_frame.
4590 * */
4591
4592 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4593 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304594
Jeff Johnson295189b2012-06-20 16:38:30 -07004595
4596 if (NULL == bss_status)
4597 {
4598 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004599 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004600 }
4601 else
4602 {
Yue Maf49ba872013-08-19 12:04:25 -07004603 cfg80211_put_bss(
4604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4605 wiphy,
4606#endif
4607 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004608 }
4609
4610 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4611 }
4612
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304613 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004614
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304615 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004616}
4617
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004618void
4619hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4620{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304621 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004622 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004623} /****** end hddPrintMacAddr() ******/
4624
4625void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004626hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004627{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304628 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004629 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004630 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4631 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4632 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004633} /****** end hddPrintPmkId() ******/
4634
4635//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4636//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4637
4638//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4639//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4640
4641#define dump_bssid(bssid) \
4642 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004643 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4644 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004645 }
4646
4647#define dump_pmkid(pMac, pmkid) \
4648 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004649 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4650 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004651 }
4652
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004653#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004654/*
4655 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4656 * This function is used to notify the supplicant of a new PMKSA candidate.
4657 */
4658int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304659 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004660 int index, bool preauth )
4661{
Jeff Johnsone7245742012-09-05 17:12:55 -07004662#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004663 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004664 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004665
4666 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004667 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004668
4669 if( NULL == pRoamInfo )
4670 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004671 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004672 return -EINVAL;
4673 }
4674
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004675 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4676 {
4677 dump_bssid(pRoamInfo->bssid);
4678 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004679 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004680 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004681#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304682 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004683}
4684#endif //FEATURE_WLAN_LFR
4685
Yue Maef608272013-04-08 23:09:17 -07004686#ifdef FEATURE_WLAN_LFR_METRICS
4687/*
4688 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4689 * 802.11r/LFR metrics reporting function to report preauth initiation
4690 *
4691 */
4692#define MAX_LFR_METRICS_EVENT_LENGTH 100
4693VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4694 tCsrRoamInfo *pRoamInfo)
4695{
4696 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4697 union iwreq_data wrqu;
4698
4699 ENTER();
4700
4701 if (NULL == pAdapter)
4702 {
4703 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4704 return VOS_STATUS_E_FAILURE;
4705 }
4706
4707 /* create the event */
4708 memset(&wrqu, 0, sizeof(wrqu));
4709 memset(metrics_notification, 0, sizeof(metrics_notification));
4710
4711 wrqu.data.pointer = metrics_notification;
4712 wrqu.data.length = scnprintf(metrics_notification,
4713 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4714 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4715
4716 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4717
4718 EXIT();
4719
4720 return VOS_STATUS_SUCCESS;
4721}
4722
4723/*
4724 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4725 * 802.11r/LFR metrics reporting function to report preauth completion
4726 * or failure
4727 */
4728VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4729 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4730{
4731 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4732 union iwreq_data wrqu;
4733
4734 ENTER();
4735
4736 if (NULL == pAdapter)
4737 {
4738 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4739 return VOS_STATUS_E_FAILURE;
4740 }
4741
4742 /* create the event */
4743 memset(&wrqu, 0, sizeof(wrqu));
4744 memset(metrics_notification, 0, sizeof(metrics_notification));
4745
4746 scnprintf(metrics_notification, sizeof(metrics_notification),
4747 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4748 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4749
4750 if (1 == preauth_status)
4751 strncat(metrics_notification, " TRUE", 5);
4752 else
4753 strncat(metrics_notification, " FALSE", 6);
4754
4755 wrqu.data.pointer = metrics_notification;
4756 wrqu.data.length = strlen(metrics_notification);
4757
4758 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4759
4760 EXIT();
4761
4762 return VOS_STATUS_SUCCESS;
4763}
4764
4765/*
4766 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4767 * 802.11r/LFR metrics reporting function to report handover initiation
4768 *
4769 */
4770VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4771 tCsrRoamInfo *pRoamInfo)
4772{
4773 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4774 union iwreq_data wrqu;
4775
4776 ENTER();
4777
4778 if (NULL == pAdapter)
4779 {
4780 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4781 return VOS_STATUS_E_FAILURE;
4782 }
4783
4784 /* create the event */
4785 memset(&wrqu, 0, sizeof(wrqu));
4786 memset(metrics_notification, 0, sizeof(metrics_notification));
4787
4788 wrqu.data.pointer = metrics_notification;
4789 wrqu.data.length = scnprintf(metrics_notification,
4790 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4791 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4792
4793 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4794
4795 EXIT();
4796
4797 return VOS_STATUS_SUCCESS;
4798}
4799#endif
4800
Jeff Johnson295189b2012-06-20 16:38:30 -07004801/*
4802 * FUNCTION: hdd_cfg80211_scan_done_callback
4803 * scanning callback function, called after finishing scan
4804 *
4805 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304806static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4808{
4809 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304810 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004812 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4813 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004814 struct cfg80211_scan_request *req = NULL;
4815 int ret = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304816 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004817
4818 ENTER();
4819
4820 hddLog(VOS_TRACE_LEVEL_INFO,
4821 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004822 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004823 __func__, halHandle, pContext, (int) scanId, (int) status);
4824
Kiet Lamac06e2c2013-10-23 16:25:07 +05304825 pScanInfo->mScanPendingCounter = 0;
4826
Jeff Johnson295189b2012-06-20 16:38:30 -07004827 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304828 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004829 &pScanInfo->scan_req_completion_event,
4830 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304831 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304833 hddLog(VOS_TRACE_LEVEL_ERROR,
4834 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004835 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004836 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004837 }
4838
Yue Maef608272013-04-08 23:09:17 -07004839 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 {
4841 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004842 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004843 }
4844
4845 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304846 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 {
4848 hddLog(VOS_TRACE_LEVEL_INFO,
4849 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004850 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 (int) scanId);
4852 }
4853
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304854 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004855 pAdapter);
4856
4857 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304858 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004859
4860
4861 /* If any client wait scan result through WEXT
4862 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004863 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 {
4865 /* The other scan request waiting for current scan finish
4866 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004867 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004868 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004869 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004870 }
4871 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004872 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004873 {
4874 struct net_device *dev = pAdapter->dev;
4875 union iwreq_data wrqu;
4876 int we_event;
4877 char *msg;
4878
4879 memset(&wrqu, '\0', sizeof(wrqu));
4880 we_event = SIOCGIWSCAN;
4881 msg = NULL;
4882 wireless_send_event(dev, we_event, &wrqu, msg);
4883 }
4884 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004885 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004886
4887 /* Get the Scan Req */
4888 req = pAdapter->request;
4889
4890 if (!req)
4891 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004892 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004893 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004894 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004895 }
4896
4897 /*
4898 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304899 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004900 req->n_ssids = 0;
4901 req->n_channels = 0;
4902 req->ie = 0;
4903
Jeff Johnson295189b2012-06-20 16:38:30 -07004904 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004905 /* Scan is no longer pending */
4906 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004907
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004908 /*
4909 * cfg80211_scan_done informing NL80211 about completion
4910 * of scanning
4911 */
4912 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004913 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004914
Jeff Johnsone7245742012-09-05 17:12:55 -07004915allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004916 /* release the wake lock at the end of the scan*/
4917 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004918
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004919 /* Acquire wakelock to handle the case where APP's tries to suspend
4920 * immediatly after the driver gets connect request(i.e after scan)
4921 * from supplicant, this result in app's is suspending and not able
4922 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304923 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004924
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004925#ifdef FEATURE_WLAN_TDLS
4926 wlan_hdd_tdls_scan_done_callback(pAdapter);
4927#endif
4928
Jeff Johnson295189b2012-06-20 16:38:30 -07004929 EXIT();
4930 return 0;
4931}
4932
4933/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004934 * FUNCTION: hdd_isScanAllowed
4935 * Go through each adapter and check if scan allowed
4936 *
4937 */
4938v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4939{
4940 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4941 hdd_station_ctx_t *pHddStaCtx = NULL;
4942 hdd_adapter_t *pAdapter = NULL;
4943 VOS_STATUS status = 0;
4944 v_U8_t staId = 0;
4945 v_U8_t *staMac = NULL;
4946
c_hpothu9b781ba2013-12-30 20:57:45 +05304947 if (TRUE == pHddCtx->btCoexModeSet)
4948 {
4949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4950 FL("BTCoex Mode operation in progress, Do not allow scan"));
4951 return VOS_FALSE;
4952 }
4953
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004954 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4955
4956 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4957 {
4958 pAdapter = pAdapterNode->pAdapter;
4959
4960 if( pAdapter )
4961 {
4962 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304963 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004964 __func__, pAdapter->device_mode);
4965 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4966 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4967 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4968 {
4969 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4970 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4971 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4972 {
4973 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4974 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004975 "%s: client " MAC_ADDRESS_STR
4976 " is in the middle of WPS/EAPOL exchange.", __func__,
4977 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004978 return VOS_FALSE;
4979 }
4980 }
4981 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4982 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4983 {
4984 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304986 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004987 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4988 {
4989 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4990
4991 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004992 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
4993 "middle of WPS/EAPOL exchange.", __func__,
4994 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004995 return VOS_FALSE;
4996 }
4997 }
4998 }
4999 }
5000 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5001 pAdapterNode = pNext;
5002 }
5003 hddLog(VOS_TRACE_LEVEL_INFO,
5004 "%s: Scan allowed", __func__);
5005 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305006}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005007
5008/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 * FUNCTION: wlan_hdd_cfg80211_scan
5010 * this scan respond to scan trigger and update cfg80211 scan database
5011 * later, scan dump command can be used to recieve scan results
5012 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005013int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5014#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5015 struct net_device *dev,
5016#endif
5017 struct cfg80211_scan_request *request)
5018{
5019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5020 struct net_device *dev = request->wdev->netdev;
5021#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5024 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305025 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005026 tCsrScanRequest scanRequest;
5027 tANI_U8 *channelList = NULL, i;
5028 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305029 int status;
5030 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005032
5033 ENTER();
5034
Arif Hussain6d2a3322013-11-17 19:50:10 -08005035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005037
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305038 status = wlan_hdd_validate_context(pHddCtx);
5039
5040 if (0 != status)
5041 {
5042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5043 "%s: HDD context is not valid", __func__);
5044 return status;
5045 }
5046
5047 cfg_param = pHddCtx->cfg_ini;
5048 pScanInfo = &pHddCtx->scan_info;
5049
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005050 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005051 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005052 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005053 {
5054 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005055 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5056 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005057 return -EBUSY;
5058 }
5059
Jeff Johnson295189b2012-06-20 16:38:30 -07005060#ifdef WLAN_BTAMP_FEATURE
5061 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005062 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005064 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005065 "%s: No scanning when AMP is on", __func__);
5066 return -EOPNOTSUPP;
5067 }
5068#endif
5069 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005070 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005072 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005073 "%s: Not scanning on device_mode = %d",
5074 __func__, pAdapter->device_mode);
5075 return -EOPNOTSUPP;
5076 }
5077
5078 if (TRUE == pScanInfo->mScanPending)
5079 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305080 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5081 {
5082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5083 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005084 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 }
5086
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005088 //Channel and action frame is pending
5089 //Otherwise Cancel Remain On Channel and allow Scan
5090 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005091 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005092 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005094 return -EBUSY;
5095 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005096#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005097 /* if tdls disagree scan right now, return immediately.
5098 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5099 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5100 */
5101 status = wlan_hdd_tdls_scan_callback (pAdapter,
5102 wiphy,
5103#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5104 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005105#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005106 request);
5107 if(status <= 0)
5108 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305109 if(!status)
5110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5111 "scan rejected %d", __func__, status);
5112 else
5113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5114 __func__, status);
5115
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005116 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005117 }
5118#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005119
Jeff Johnson295189b2012-06-20 16:38:30 -07005120 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5121 {
5122 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005123 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305125 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5127 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305128 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 "%s: MAX TM Level Scan not allowed", __func__);
5130 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305131 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 }
5133 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5134
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005135 /* Check if scan is allowed at this point of time.
5136 */
5137 if (!hdd_isScanAllowed(pHddCtx))
5138 {
5139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5140 return -EBUSY;
5141 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305142
Jeff Johnson295189b2012-06-20 16:38:30 -07005143 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5144
5145 if (NULL != request)
5146 {
5147 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305148 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005149
5150 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5151 * Becasue of this, driver is assuming that this is not wildcard scan and so
5152 * is not aging out the scan results.
5153 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005154 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005155 {
5156 request->n_ssids = 0;
5157 }
5158
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005159 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 {
5161 tCsrSSIDInfo *SsidInfo;
5162 int j;
5163 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5164 /* Allocate num_ssid tCsrSSIDInfo structure */
5165 SsidInfo = scanRequest.SSIDs.SSIDList =
5166 ( tCsrSSIDInfo *)vos_mem_malloc(
5167 request->n_ssids*sizeof(tCsrSSIDInfo));
5168
5169 if(NULL == scanRequest.SSIDs.SSIDList)
5170 {
5171 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305172 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005173 return -ENOMEM;
5174 }
5175
5176 /* copy all the ssid's and their length */
5177 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5178 {
5179 /* get the ssid length */
5180 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5181 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5182 SsidInfo->SSID.length);
5183 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305184 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005185 j, SsidInfo->SSID.ssId);
5186 }
5187 /* set the scan type to active */
5188 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5189 }
5190 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5191 {
5192 /* set the scan type to active */
5193 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5194 }
5195 else
5196 {
5197 /*Set the scan type to default type, in this case it is ACTIVE*/
5198 scanRequest.scanType = pScanInfo->scan_mode;
5199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305200 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5202 }
5203 else
5204 {
5205 /* set the scan type to active */
5206 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5207 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5208
5209 /* set min and max channel time to zero */
5210 scanRequest.minChnTime = 0;
5211 scanRequest.maxChnTime = 0;
5212 }
5213
5214 /* set BSSType to default type */
5215 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5216
5217 /*TODO: scan the requested channels only*/
5218
5219 /*Right now scanning all the channels */
5220 if( request )
5221 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305222 hddLog(VOS_TRACE_LEVEL_INFO,
5223 "No of Scan Channels: %d", request->n_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 if( request->n_channels )
5225 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305226 char chList [(request->n_channels*5)+1];
5227 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005228 channelList = vos_mem_malloc( request->n_channels );
5229 if( NULL == channelList )
5230 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305231 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305232 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 status = -ENOMEM;
5234 goto free_mem;
5235 }
5236
Nirav Shah20ac06f2013-12-12 18:14:06 +05305237 for( i = 0, len = 0; i < request->n_channels ; i++ )
5238 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305240 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5241 }
5242
5243 hddLog(VOS_TRACE_LEVEL_INFO,
5244 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 }
5246
5247 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5248 scanRequest.ChannelInfo.ChannelList = channelList;
5249
5250 /* set requestType to full scan */
5251 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305252
5253 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005254 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305255 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005256 */
5257
5258 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305259 * and in that case driver shoudnt flush scan results. If
5260 * driver flushes the scan results here and unfortunately if
5261 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005262 * fails which is not desired
5263 */
5264
5265 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5266 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305267 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005268 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5269 pAdapter->sessionId );
5270 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005271
5272 if( request->ie_len )
5273 {
5274 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305275 /*TODO: Array needs to be converted to dynamic allocation,
5276 * as multiple ie.s can be sent in cfg80211_scan_request structure
5277 * CR 597966
5278 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5280 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5281 pScanInfo->scanAddIE.length = request->ie_len;
5282
Agarwal Ashish4f616132013-12-30 23:32:50 +05305283 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005284 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305285 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305287 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5288 {
5289 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5290 memcpy( pwextBuf->roamProfile.addIEScan,
5291 request->ie, request->ie_len);
5292 }
5293 else
5294 {
5295 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5296 "%d", request->ie_len);
5297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005298
Agarwal Ashish4f616132013-12-30 23:32:50 +05305299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005300 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5301 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5302
Jeff Johnson295189b2012-06-20 16:38:30 -07005303 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5304 request->ie_len);
5305 if (pP2pIe != NULL)
5306 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005307#ifdef WLAN_FEATURE_P2P_DEBUG
5308 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5309 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5310 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5311 {
5312 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5313 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5314 "Go nego completed to Connection is started");
5315 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5316 "for 8way Handshake");
5317 }
5318 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5319 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5320 {
5321 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5322 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5323 "Disconnected state to Connection is started");
5324 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5325 "for 4way Handshake");
5326 }
5327#endif
5328
Jeff Johnsone7245742012-09-05 17:12:55 -07005329 /* no_cck will be set during p2p find to disable 11b rates */
5330 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 hddLog(VOS_TRACE_LEVEL_INFO,
5333 "%s: This is a P2P Search", __func__);
5334 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005335
Jeff Johnsone7245742012-09-05 17:12:55 -07005336 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5337 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005338 /* set requestType to P2P Discovery */
5339 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005340 }
5341
5342 /*
5343 Skip Dfs Channel in case of P2P Search
5344 if it is set in ini file
5345 */
5346 if(cfg_param->skipDfsChnlInP2pSearch)
5347 {
5348 scanRequest.skipDfsChnlInP2pSearch = 1;
5349 }
5350 else
5351 {
5352 scanRequest.skipDfsChnlInP2pSearch = 0;
5353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005354
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 }
5356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 }
5358 }
5359
5360 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5361
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005362 /* acquire the wakelock to avoid the apps suspend during the scan. To
5363 * address the following issues.
5364 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5365 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5366 * for long time, this result in apps running at full power for long time.
5367 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5368 * be stuck in full power because of resume BMPS
5369 */
5370 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005371
Nirav Shah20ac06f2013-12-12 18:14:06 +05305372 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5373 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5374 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5375 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5376 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5377
Jeff Johnsone7245742012-09-05 17:12:55 -07005378 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 pAdapter->sessionId, &scanRequest, &scanId,
5380 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005381
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 if (eHAL_STATUS_SUCCESS != status)
5383 {
5384 hddLog(VOS_TRACE_LEVEL_ERROR,
5385 "%s: sme_ScanRequest returned error %d", __func__, status);
5386 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005387 if(eHAL_STATUS_RESOURCES == status)
5388 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5390 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005391 status = -EBUSY;
5392 } else {
5393 status = -EIO;
5394 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005395 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005396 goto free_mem;
5397 }
5398
5399 pScanInfo->mScanPending = TRUE;
5400 pAdapter->request = request;
5401 pScanInfo->scanId = scanId;
5402
5403 complete(&pScanInfo->scan_req_completion_event);
5404
5405free_mem:
5406 if( scanRequest.SSIDs.SSIDList )
5407 {
5408 vos_mem_free(scanRequest.SSIDs.SSIDList);
5409 }
5410
5411 if( channelList )
5412 vos_mem_free( channelList );
5413
5414 EXIT();
5415
5416 return status;
5417}
5418
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005419
5420void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5421{
5422 v_U8_t iniDot11Mode =
5423 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5424 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5425
5426 switch ( iniDot11Mode )
5427 {
5428 case eHDD_DOT11_MODE_AUTO:
5429 case eHDD_DOT11_MODE_11ac:
5430 case eHDD_DOT11_MODE_11ac_ONLY:
5431#ifdef WLAN_FEATURE_11AC
5432 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5433#else
5434 hddDot11Mode = eHDD_DOT11_MODE_11n;
5435#endif
5436 break;
5437 case eHDD_DOT11_MODE_11n:
5438 case eHDD_DOT11_MODE_11n_ONLY:
5439 hddDot11Mode = eHDD_DOT11_MODE_11n;
5440 break;
5441 default:
5442 hddDot11Mode = iniDot11Mode;
5443 break;
5444 }
5445 /* This call decides required channel bonding mode */
5446 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5447 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5448 operationChannel);
5449}
5450
Jeff Johnson295189b2012-06-20 16:38:30 -07005451/*
5452 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305455int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005456 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005457{
5458 int status = 0;
5459 hdd_wext_state_t *pWextState;
5460 v_U32_t roamId;
5461 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 eCsrAuthType RSNAuthType;
5463
5464 ENTER();
5465
5466 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305467
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5469 {
5470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5471 return -EINVAL;
5472 }
5473
5474 pRoamProfile = &pWextState->roamProfile;
5475
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305476 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005478 hdd_station_ctx_t *pHddStaCtx;
5479 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005480
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305481 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5483 {
5484 /*QoS not enabled in cfg file*/
5485 pRoamProfile->uapsd_mask = 0;
5486 }
5487 else
5488 {
5489 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305490 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5492 }
5493
5494 pRoamProfile->SSIDs.numOfSSIDs = 1;
5495 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5496 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305497 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5499 ssid, ssid_len);
5500
5501 if (bssid)
5502 {
5503 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5504 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5505 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305506 /* Save BSSID in seperate variable as well, as RoamProfile
5507 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 case of join failure we should send valid BSSID to supplicant
5509 */
5510 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5511 WNI_CFG_BSSID_LEN);
5512 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005513 else
5514 {
5515 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005517
5518 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5519 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305520 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 /*set gen ie*/
5522 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5523 /*set auth*/
5524 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005526#ifdef FEATURE_WLAN_WAPI
5527 if (pAdapter->wapi_info.nWapiMode)
5528 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005529 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005530 switch (pAdapter->wapi_info.wapiAuthMode)
5531 {
5532 case WAPI_AUTH_MODE_PSK:
5533 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005534 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 pAdapter->wapi_info.wapiAuthMode);
5536 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5537 break;
5538 }
5539 case WAPI_AUTH_MODE_CERT:
5540 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005541 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 pAdapter->wapi_info.wapiAuthMode);
5543 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5544 break;
5545 }
5546 } // End of switch
5547 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5548 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5549 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005550 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 pRoamProfile->AuthType.numEntries = 1;
5552 pRoamProfile->EncryptionType.numEntries = 1;
5553 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5554 pRoamProfile->mcEncryptionType.numEntries = 1;
5555 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5556 }
5557 }
5558#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305559#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305560 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305561 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5562 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5563 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305564 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5565 sizeof (tSirGtkOffloadParams));
5566 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305567 }
5568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 pRoamProfile->csrPersona = pAdapter->device_mode;
5570
Jeff Johnson32d95a32012-09-10 13:15:23 -07005571 if( operatingChannel )
5572 {
5573 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5574 pRoamProfile->ChannelInfo.numOfChannels = 1;
5575 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005576 else
5577 {
5578 pRoamProfile->ChannelInfo.ChannelList = NULL;
5579 pRoamProfile->ChannelInfo.numOfChannels = 0;
5580 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005581 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5582 {
5583 hdd_select_cbmode(pAdapter,operatingChannel);
5584 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005585 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5586 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005588 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005589 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5590 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305591 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5592 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005593 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5594 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305595
5596 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 pAdapter->sessionId, pRoamProfile, &roamId);
5598
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305599 if ((eHAL_STATUS_SUCCESS != status) &&
5600 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5601 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305602
5603 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5605 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5606 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305607 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005608 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305609 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005610
5611 pRoamProfile->ChannelInfo.ChannelList = NULL;
5612 pRoamProfile->ChannelInfo.numOfChannels = 0;
5613
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 }
5615 else
5616 {
5617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5618 return -EINVAL;
5619 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005620 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 return status;
5622}
5623
5624/*
5625 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5626 * This function is used to set the authentication type (OPEN/SHARED).
5627 *
5628 */
5629static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5630 enum nl80211_auth_type auth_type)
5631{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305632 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5634
5635 ENTER();
5636
5637 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305638 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305641 hddLog(VOS_TRACE_LEVEL_INFO,
5642 "%s: set authentication type to AUTOSWITCH", __func__);
5643 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5644 break;
5645
5646 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005647#ifdef WLAN_FEATURE_VOWIFI_11R
5648 case NL80211_AUTHTYPE_FT:
5649#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305650 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005651 "%s: set authentication type to OPEN", __func__);
5652 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5653 break;
5654
5655 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305656 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005657 "%s: set authentication type to SHARED", __func__);
5658 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5659 break;
5660#ifdef FEATURE_WLAN_CCX
5661 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305662 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005663 "%s: set authentication type to CCKM WPA", __func__);
5664 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5665 break;
5666#endif
5667
5668
5669 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305670 hddLog(VOS_TRACE_LEVEL_ERROR,
5671 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 auth_type);
5673 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5674 return -EINVAL;
5675 }
5676
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305677 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 pHddStaCtx->conn_info.authType;
5679 return 0;
5680}
5681
5682/*
5683 * FUNCTION: wlan_hdd_set_akm_suite
5684 * This function is used to set the key mgmt type(PSK/8021x).
5685 *
5686 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305687static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 u32 key_mgmt
5689 )
5690{
5691 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5692 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305693
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 /*set key mgmt type*/
5695 switch(key_mgmt)
5696 {
5697 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305698#ifdef WLAN_FEATURE_VOWIFI_11R
5699 case WLAN_AKM_SUITE_FT_PSK:
5700#endif
5701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 __func__);
5703 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5704 break;
5705
5706 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305707#ifdef WLAN_FEATURE_VOWIFI_11R
5708 case WLAN_AKM_SUITE_FT_8021X:
5709#endif
5710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 __func__);
5712 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5713 break;
5714#ifdef FEATURE_WLAN_CCX
5715#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5716#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5717 case WLAN_AKM_SUITE_CCKM:
5718 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5719 __func__);
5720 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5721 break;
5722#endif
5723
5724 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005726 __func__, key_mgmt);
5727 return -EINVAL;
5728
5729 }
5730 return 0;
5731}
5732
5733/*
5734 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305735 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 * (NONE/WEP40/WEP104/TKIP/CCMP).
5737 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305738static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5739 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 bool ucast
5741 )
5742{
5743 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305744 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5746
5747 ENTER();
5748
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 __func__, cipher);
5753 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5754 }
5755 else
5756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305757
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305759 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 {
5761 case IW_AUTH_CIPHER_NONE:
5762 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5763 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305764
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305766 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305768
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305770 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305772
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 case WLAN_CIPHER_SUITE_TKIP:
5774 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5775 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305776
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 case WLAN_CIPHER_SUITE_CCMP:
5778 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5779 break;
5780#ifdef FEATURE_WLAN_WAPI
5781 case WLAN_CIPHER_SUITE_SMS4:
5782 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5783 break;
5784#endif
5785
5786#ifdef FEATURE_WLAN_CCX
5787 case WLAN_CIPHER_SUITE_KRK:
5788 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5789 break;
5790#endif
5791 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 __func__, cipher);
5794 return -EOPNOTSUPP;
5795 }
5796 }
5797
5798 if (ucast)
5799 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 __func__, encryptionType);
5802 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5803 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305804 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 encryptionType;
5806 }
5807 else
5808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 __func__, encryptionType);
5811 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5812 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5813 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5814 }
5815
5816 return 0;
5817}
5818
5819
5820/*
5821 * FUNCTION: wlan_hdd_cfg80211_set_ie
5822 * This function is used to parse WPA/RSN IE's.
5823 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5825 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 size_t ie_len
5827 )
5828{
5829 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5830 u8 *genie = ie;
5831 v_U16_t remLen = ie_len;
5832#ifdef FEATURE_WLAN_WAPI
5833 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5834 u16 *tmp;
5835 v_U16_t akmsuiteCount;
5836 int *akmlist;
5837#endif
5838 ENTER();
5839
5840 /* clear previous assocAddIE */
5841 pWextState->assocAddIE.length = 0;
5842 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5843
5844 while (remLen >= 2)
5845 {
5846 v_U16_t eLen = 0;
5847 v_U8_t elementId;
5848 elementId = *genie++;
5849 eLen = *genie++;
5850 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305851
Arif Hussain6d2a3322013-11-17 19:50:10 -08005852 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305854
5855 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305857 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005858 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 -07005859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305860 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 "%s: Invalid WPA IE", __func__);
5862 return -EINVAL;
5863 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 {
5866 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305867 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305869
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5871 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005872 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5873 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 VOS_ASSERT(0);
5875 return -ENOMEM;
5876 }
5877 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5878 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5879 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5882 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5883 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5884 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5886 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5888 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5889 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5890 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5891 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5892 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305893 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305894 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 {
5896 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305897 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5901 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005902 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5903 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 VOS_ASSERT(0);
5905 return -ENOMEM;
5906 }
5907 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5908 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5909 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305910
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5912 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005914#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5916 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 /*Consider WFD IE, only for P2P Client */
5918 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5919 {
5920 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305921 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305923
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5925 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005926 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5927 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 VOS_ASSERT(0);
5929 return -ENOMEM;
5930 }
5931 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5932 // WPS IE + P2P IE + WFD IE
5933 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5934 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305935
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5937 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5938 }
5939#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005940 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305941 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005942 HS20_OUI_TYPE_SIZE)) )
5943 {
5944 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305945 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005946 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005947
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005948 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5949 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005950 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5951 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005952 VOS_ASSERT(0);
5953 return -ENOMEM;
5954 }
5955 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5956 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005957
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005958 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5959 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5960 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005961
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07005962 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
5963
5964 /* populating as ADDIE in beacon frames */
5965 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5966 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
5967 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
5968 {
5969 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5970 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5971 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5972 {
5973 hddLog(LOGE,
5974 "Coldn't pass "
5975 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
5976 }
5977 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
5978 else
5979 hddLog(LOGE,
5980 "Could not pass on "
5981 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
5982
5983 /* IBSS mode doesn't contain params->proberesp_ies still
5984 beaconIE's need to be populated in probe response frames */
5985 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
5986 {
5987 u16 rem_probe_resp_ie_len = eLen + 2;
5988 u8 probe_rsp_ie_len[3] = {0};
5989 u8 counter = 0;
5990
5991 /* Check Probe Resp Length if it is greater then 255 then
5992 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
5993 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
5994 not able Store More then 255 bytes into One Variable */
5995
5996 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5997 {
5998 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5999 {
6000 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6001 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6002 }
6003 else
6004 {
6005 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6006 rem_probe_resp_ie_len = 0;
6007 }
6008 }
6009
6010 rem_probe_resp_ie_len = 0;
6011
6012 if (probe_rsp_ie_len[0] > 0)
6013 {
6014 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6015 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6016 (tANI_U8*)(genie - 2),
6017 probe_rsp_ie_len[0], NULL,
6018 eANI_BOOLEAN_FALSE)
6019 == eHAL_STATUS_FAILURE)
6020 {
6021 hddLog(LOGE,
6022 "Could not pass"
6023 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6024 }
6025 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6026 }
6027
6028 if (probe_rsp_ie_len[1] > 0)
6029 {
6030 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6031 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6032 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6033 probe_rsp_ie_len[1], NULL,
6034 eANI_BOOLEAN_FALSE)
6035 == eHAL_STATUS_FAILURE)
6036 {
6037 hddLog(LOGE,
6038 "Could not pass"
6039 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6040 }
6041 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6042 }
6043
6044 if (probe_rsp_ie_len[2] > 0)
6045 {
6046 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6047 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6048 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6049 probe_rsp_ie_len[2], NULL,
6050 eANI_BOOLEAN_FALSE)
6051 == eHAL_STATUS_FAILURE)
6052 {
6053 hddLog(LOGE,
6054 "Could not pass"
6055 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6056 }
6057 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6058 }
6059
6060 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6061 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6062 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6063 {
6064 hddLog(LOGE,
6065 "Could not pass"
6066 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6067 }
6068 }
6069 else
6070 {
6071 // Reset WNI_CFG_PROBE_RSP Flags
6072 wlan_hdd_reset_prob_rspies(pAdapter);
6073
6074 hddLog(VOS_TRACE_LEVEL_INFO,
6075 "%s: No Probe Response IE received in set beacon",
6076 __func__);
6077 }
6078 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 break;
6080 case DOT11F_EID_RSN:
6081 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6082 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6083 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6084 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6085 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6086 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006087 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6088 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306089 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006090 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306091 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006092 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006094 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6095 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006096 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6097 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006098 VOS_ASSERT(0);
6099 return -ENOMEM;
6100 }
6101 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6102 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006104 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6105 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6106 break;
6107 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006108#ifdef FEATURE_WLAN_WAPI
6109 case WLAN_EID_WAPI:
6110 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006111 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 pAdapter->wapi_info.nWapiMode);
6113 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306114 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 akmsuiteCount = WPA_GET_LE16(tmp);
6116 tmp = tmp + 1;
6117 akmlist = (int *)(tmp);
6118 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6119 {
6120 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6121 }
6122 else
6123 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006124 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 VOS_ASSERT(0);
6126 return -EINVAL;
6127 }
6128
6129 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6130 {
6131 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006132 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306134 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306136 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006138 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6140 }
6141 break;
6142#endif
6143 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306144 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006146 /* when Unknown IE is received we should break and continue
6147 * to the next IE in the buffer instead we were returning
6148 * so changing this to break */
6149 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 }
6151 genie += eLen;
6152 remLen -= eLen;
6153 }
6154 EXIT();
6155 return 0;
6156}
6157
6158/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306159 * FUNCTION: hdd_isWPAIEPresent
6160 * Parse the received IE to find the WPA IE
6161 *
6162 */
6163static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6164{
6165 v_U8_t eLen = 0;
6166 v_U16_t remLen = ie_len;
6167 v_U8_t elementId = 0;
6168
6169 while (remLen >= 2)
6170 {
6171 elementId = *ie++;
6172 eLen = *ie++;
6173 remLen -= 2;
6174 if (eLen > remLen)
6175 {
6176 hddLog(VOS_TRACE_LEVEL_ERROR,
6177 "%s: IE length is wrong %d", __func__, eLen);
6178 return FALSE;
6179 }
6180 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6181 {
6182 /* OUI - 0x00 0X50 0XF2
6183 WPA Information Element - 0x01
6184 WPA version - 0x01*/
6185 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6186 return TRUE;
6187 }
6188 ie += eLen;
6189 remLen -= eLen;
6190 }
6191 return FALSE;
6192}
6193
6194/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306196 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 * parameters during connect operation.
6198 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306199int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 struct cfg80211_connect_params *req
6201 )
6202{
6203 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306204 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 ENTER();
6206
6207 /*set wpa version*/
6208 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6209
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306210 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306212 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 {
6214 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6215 }
6216 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6217 {
6218 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6219 }
6220 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306221
6222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 pWextState->wpaVersion);
6224
6225 /*set authentication type*/
6226 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6227
6228 if (0 > status)
6229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306230 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 "%s: failed to set authentication type ", __func__);
6232 return status;
6233 }
6234
6235 /*set key mgmt type*/
6236 if (req->crypto.n_akm_suites)
6237 {
6238 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6239 if (0 > status)
6240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 __func__);
6243 return status;
6244 }
6245 }
6246
6247 /*set pairwise cipher type*/
6248 if (req->crypto.n_ciphers_pairwise)
6249 {
6250 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6251 req->crypto.ciphers_pairwise[0], true);
6252 if (0 > status)
6253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306254 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 "%s: failed to set unicast cipher type", __func__);
6256 return status;
6257 }
6258 }
6259 else
6260 {
6261 /*Reset previous cipher suite to none*/
6262 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6263 if (0 > status)
6264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306265 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 "%s: failed to set unicast cipher type", __func__);
6267 return status;
6268 }
6269 }
6270
6271 /*set group cipher type*/
6272 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6273 false);
6274
6275 if (0 > status)
6276 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 __func__);
6279 return status;
6280 }
6281
Chet Lanctot186b5732013-03-18 10:26:30 -07006282#ifdef WLAN_FEATURE_11W
6283 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6284#endif
6285
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6287 if (req->ie_len)
6288 {
6289 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6290 if ( 0 > status)
6291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 __func__);
6294 return status;
6295 }
6296 }
6297
6298 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306299 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 {
6301 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6302 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6303 )
6304 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306305 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6307 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 __func__);
6310 return -EOPNOTSUPP;
6311 }
6312 else
6313 {
6314 u8 key_len = req->key_len;
6315 u8 key_idx = req->key_idx;
6316
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306317 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 && (CSR_MAX_NUM_KEY > key_idx)
6319 )
6320 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306321 hddLog(VOS_TRACE_LEVEL_INFO,
6322 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 __func__, key_idx, key_len);
6324 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306325 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306327 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 (u8)key_len;
6329 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6330 }
6331 }
6332 }
6333 }
6334
6335 return status;
6336}
6337
6338/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306339 * FUNCTION: wlan_hdd_try_disconnect
6340 * This function is used to disconnect from previous
6341 * connection
6342 */
6343static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6344{
6345 long ret = 0;
6346 hdd_station_ctx_t *pHddStaCtx;
6347 eMib_dot11DesiredBssType connectedBssType;
6348
6349 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6350
6351 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6352
6353 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6354 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6355 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6356 {
6357 /* Issue disconnect to CSR */
6358 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6359 if( eHAL_STATUS_SUCCESS ==
6360 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6361 pAdapter->sessionId,
6362 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6363 {
6364 ret = wait_for_completion_interruptible_timeout(
6365 &pAdapter->disconnect_comp_var,
6366 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6367 if (0 >= ret)
6368 {
6369 hddLog(LOGE, FL("Failed to receive disconnect event"));
6370 return -EALREADY;
6371 }
6372 }
6373 }
6374 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6375 {
6376 ret = wait_for_completion_interruptible_timeout(
6377 &pAdapter->disconnect_comp_var,
6378 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6379 if (0 >= ret)
6380 {
6381 hddLog(LOGE, FL("Failed to receive disconnect event"));
6382 return -EALREADY;
6383 }
6384 }
6385
6386 return 0;
6387}
6388
6389/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306391 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 * parameters during connect operation.
6393 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306394static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 struct net_device *ndev,
6396 struct cfg80211_connect_params *req
6397 )
6398{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306399 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306400 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006402 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006403
6404 ENTER();
6405
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006406 if (!pAdapter)
6407 {
6408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6409 "%s: Adapter context is null", __func__);
6410 return VOS_STATUS_E_FAILURE;
6411 }
6412
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306413 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006414 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006415
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306416 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006417 if (!pHddCtx)
6418 {
6419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6420 "%s: HDD context is null", __func__);
6421 return VOS_STATUS_E_FAILURE;
6422 }
6423
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306424 status = wlan_hdd_validate_context(pHddCtx);
6425
6426 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6429 "%s: HDD context is not valid", __func__);
6430 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 }
6432
6433#ifdef WLAN_BTAMP_FEATURE
6434 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306435 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306437 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006439 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 }
6441#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306442
6443 //If Device Mode is Station Concurrent Sessions Exit BMps
6444 //P2P Mode will be taken care in Open/close adapter
6445 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6446 (vos_concurrent_sessions_running()))
6447 {
6448 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6449 }
6450
6451 /*Try disconnecting if already in connected state*/
6452 status = wlan_hdd_try_disconnect(pAdapter);
6453 if ( 0 > status)
6454 {
6455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6456 " connection"));
6457 return -EALREADY;
6458 }
6459
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306461 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006462
6463 if ( 0 > status)
6464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 __func__);
6467 return status;
6468 }
6469
Mohit Khanna765234a2012-09-11 15:08:35 -07006470 if ( req->channel )
6471 {
6472 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6473 req->ssid_len, req->bssid,
6474 req->channel->hw_value);
6475 }
6476 else
6477 {
6478 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306479 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006481
6482 if (0 > status)
6483 {
6484 //ReEnable BMPS if disabled
6485 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6486 (NULL != pHddCtx))
6487 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306488 if (pHddCtx->hdd_wlan_suspended)
6489 {
6490 hdd_set_pwrparams(pHddCtx);
6491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 //ReEnable Bmps and Imps back
6493 hdd_enable_bmps_imps(pHddCtx);
6494 }
6495
6496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6497 return status;
6498 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306499 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 EXIT();
6501 return status;
6502}
6503
6504
6505/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306506 * FUNCTION: wlan_hdd_disconnect
6507 * This function is used to issue a disconnect request to SME
6508 */
6509int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6510{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306511 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306512 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306513 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306514 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306515
6516 status = wlan_hdd_validate_context(pHddCtx);
6517
6518 if (0 != status)
6519 {
6520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6521 "%s: HDD context is not valid", __func__);
6522 return status;
6523 }
6524
6525 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306526 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306527 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306528
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306529 /*issue disconnect*/
6530 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6531 pAdapter->sessionId, reason);
6532
6533 if ( 0 != status )
6534 {
6535 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006536 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306537 __func__, (int)status );
6538 return -EINVAL;
6539 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306540 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306541 &pAdapter->disconnect_comp_var,
6542 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306543 if (ret <= 0)
6544 {
6545 hddLog(VOS_TRACE_LEVEL_ERROR,
6546 FL("wait on disconnect_comp_var failed %ld"), ret);
6547 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306548 /*stop tx queues*/
6549 netif_tx_disable(pAdapter->dev);
6550 netif_carrier_off(pAdapter->dev);
6551 return status;
6552}
6553
6554
6555/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 * FUNCTION: wlan_hdd_cfg80211_disconnect
6557 * This function is used to issue a disconnect request to SME
6558 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306559static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 struct net_device *dev,
6561 u16 reason
6562 )
6563{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6565 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306567 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006568 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006569 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306570#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006571 tANI_U8 staIdx;
6572#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306573
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306575
Arif Hussain6d2a3322013-11-17 19:50:10 -08006576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 __func__,pAdapter->device_mode);
6578
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6580 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006581
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306582 status = wlan_hdd_validate_context(pHddCtx);
6583
6584 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6587 "%s: HDD context is not valid", __func__);
6588 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306590
Jeff Johnson295189b2012-06-20 16:38:30 -07006591 if (NULL != pRoamProfile)
6592 {
6593 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306594 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6595 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306597 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306599 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 switch(reason)
6601 {
6602 case WLAN_REASON_MIC_FAILURE:
6603 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6604 break;
6605
6606 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6607 case WLAN_REASON_DISASSOC_AP_BUSY:
6608 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6609 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6610 break;
6611
6612 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6613 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6614 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6615 break;
6616
6617 case WLAN_REASON_DEAUTH_LEAVING:
6618 default:
6619 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6620 break;
6621 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306622 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6623 pScanInfo = &pHddCtx->scan_info;
6624 if (pScanInfo->mScanPending)
6625 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306626 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306627 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306628 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6629 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006631
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006632#ifdef FEATURE_WLAN_TDLS
6633 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006634 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006635 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006636 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6637 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006638 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006639 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006640 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006641 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006642 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006643 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006644 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006645 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006646 pAdapter->sessionId,
6647 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006648 }
6649 }
6650#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306651 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6652 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 {
6654 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006655 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 __func__, (int)status );
6657 return -EINVAL;
6658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006659 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306660 else
6661 {
6662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6663 "called while in %d state", __func__,
6664 pHddStaCtx->conn_info.connState);
6665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 }
6667 else
6668 {
6669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6670 }
6671
6672 return status;
6673}
6674
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306675
Jeff Johnson295189b2012-06-20 16:38:30 -07006676/*
6677 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306678 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006679 * settings in IBSS mode.
6680 */
6681static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306682 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 struct cfg80211_ibss_params *params
6684 )
6685{
6686 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306687 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306690
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 ENTER();
6692
6693 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006694 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006695
6696 if (params->ie_len && ( NULL != params->ie) )
6697 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006698 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6699 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 {
6701 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6702 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6703 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006704 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006706 tDot11fIEWPA dot11WPAIE;
6707 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006708 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006709
Wilson Yang00256342013-10-10 23:13:38 -07006710 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006711 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6712 params->ie_len, DOT11F_EID_WPA);
6713 if ( NULL != ie )
6714 {
6715 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6716 // Unpack the WPA IE
6717 //Skip past the EID byte and length byte - and four byte WiFi OUI
6718 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6719 &ie[2+4],
6720 ie[1] - 4,
6721 &dot11WPAIE);
6722 /*Extract the multicast cipher, the encType for unicast
6723 cipher for wpa-none is none*/
6724 encryptionType =
6725 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006728
Jeff Johnson295189b2012-06-20 16:38:30 -07006729 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6730
6731 if (0 > status)
6732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 __func__);
6735 return status;
6736 }
6737 }
6738
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306739 pWextState->roamProfile.AuthType.authType[0] =
6740 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6742
6743 if (params->privacy)
6744 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306745 /* Security enabled IBSS, At this time there is no information available
6746 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306748 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006749 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306750 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 *enable privacy bit in beacons */
6752
6753 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6754 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006755 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6756 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6758 pWextState->roamProfile.EncryptionType.numEntries = 1;
6759 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 return status;
6761}
6762
6763/*
6764 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306765 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306767static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 struct net_device *dev,
6769 struct cfg80211_ibss_params *params
6770 )
6771{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6774 tCsrRoamProfile *pRoamProfile;
6775 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006776 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306778 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006779
6780 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306781
6782 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006783 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006784
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306785 status = wlan_hdd_validate_context(pHddCtx);
6786
6787 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6790 "%s: HDD context is not valid", __func__);
6791 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 }
6793
6794 if (NULL == pWextState)
6795 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006796 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 __func__);
6798 return -EIO;
6799 }
6800
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306801 /*Try disconnecting if already in connected state*/
6802 status = wlan_hdd_try_disconnect(pAdapter);
6803 if ( 0 > status)
6804 {
6805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6806 " IBSS connection"));
6807 return -EALREADY;
6808 }
6809
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 pRoamProfile = &pWextState->roamProfile;
6811
6812 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6813 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306814 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006815 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 return -EINVAL;
6817 }
6818
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006819 /* BSSID is provided by upper layers hence no need to AUTO generate */
6820 if (NULL != params->bssid) {
6821 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6822 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6823 hddLog (VOS_TRACE_LEVEL_ERROR,
6824 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6825 return -EIO;
6826 }
6827 }
krunal sonie9002db2013-11-25 14:24:17 -08006828 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6829 {
6830 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6831 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6832 {
6833 hddLog (VOS_TRACE_LEVEL_ERROR,
6834 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6835 return -EIO;
6836 }
6837 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6838 if (!params->bssid)
6839 {
6840 hddLog (VOS_TRACE_LEVEL_ERROR,
6841 "%s:Failed memory allocation", __func__);
6842 return -EIO;
6843 }
6844 vos_mem_copy((v_U8_t *)params->bssid,
6845 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6846 VOS_MAC_ADDR_SIZE);
6847 alloc_bssid = VOS_TRUE;
6848 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006849
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006851 if (NULL !=
6852#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6853 params->chandef.chan)
6854#else
6855 params->channel)
6856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 {
6858 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006859 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6860 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6861 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6862 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006863
6864 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306865 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006866 ieee80211_frequency_to_channel(
6867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6868 params->chandef.chan->center_freq);
6869#else
6870 params->channel->center_freq);
6871#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006872
6873 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6874 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6877 __func__);
6878 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006880
6881 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006883 if (channelNum == validChan[indx])
6884 {
6885 break;
6886 }
6887 }
6888 if (indx >= numChans)
6889 {
6890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 __func__, channelNum);
6892 return -EINVAL;
6893 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006894 /* Set the Operational Channel */
6895 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6896 channelNum);
6897 pRoamProfile->ChannelInfo.numOfChannels = 1;
6898 pHddStaCtx->conn_info.operationChannel = channelNum;
6899 pRoamProfile->ChannelInfo.ChannelList =
6900 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 }
6902
6903 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306904 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 if (status < 0)
6906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006908 __func__);
6909 return status;
6910 }
6911
6912 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306913 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006914 params->ssid_len, params->bssid,
6915 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006916
6917 if (0 > status)
6918 {
6919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6920 return status;
6921 }
6922
krunal sonie9002db2013-11-25 14:24:17 -08006923 if (NULL != params->bssid &&
6924 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
6925 alloc_bssid == VOS_TRUE)
6926 {
6927 vos_mem_free(params->bssid);
6928 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 return 0;
6930}
6931
6932/*
6933 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306934 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306936static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 struct net_device *dev
6938 )
6939{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306940 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6942 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306943 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6944 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006945
6946 ENTER();
6947
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306948 status = wlan_hdd_validate_context(pHddCtx);
6949
6950 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6953 "%s: HDD context is not valid", __func__);
6954 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006955 }
6956
Arif Hussain6d2a3322013-11-17 19:50:10 -08006957 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 if (NULL == pWextState)
6959 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006960 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 __func__);
6962 return -EIO;
6963 }
6964
6965 pRoamProfile = &pWextState->roamProfile;
6966
6967 /* Issue disconnect only if interface type is set to IBSS */
6968 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6969 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306970 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 __func__);
6972 return -EINVAL;
6973 }
6974
6975 /* Issue Disconnect request */
6976 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6977 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6978 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6979
6980 return 0;
6981}
6982
6983/*
6984 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6985 * This function is used to set the phy parameters
6986 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6987 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306988static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 u32 changed)
6990{
6991 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6992 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306993 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006994
6995 ENTER();
6996
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306997 status = wlan_hdd_validate_context(pHddCtx);
6998
6999 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007000 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7002 "%s: HDD context is not valid", __func__);
7003 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007004 }
7005
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7007 {
7008 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7009 WNI_CFG_RTS_THRESHOLD_STAMAX :
7010 wiphy->rts_threshold;
7011
7012 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307013 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307015 hddLog(VOS_TRACE_LEVEL_ERROR,
7016 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 __func__, rts_threshold);
7018 return -EINVAL;
7019 }
7020
7021 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7022 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307023 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307025 hddLog(VOS_TRACE_LEVEL_ERROR,
7026 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 __func__, rts_threshold);
7028 return -EIO;
7029 }
7030
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307031 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 rts_threshold);
7033 }
7034
7035 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7036 {
7037 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7038 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7039 wiphy->frag_threshold;
7040
7041 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307042 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307044 hddLog(VOS_TRACE_LEVEL_ERROR,
7045 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 frag_threshold);
7047 return -EINVAL;
7048 }
7049
7050 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7051 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307052 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307054 hddLog(VOS_TRACE_LEVEL_ERROR,
7055 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 __func__, frag_threshold);
7057 return -EIO;
7058 }
7059
7060 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7061 frag_threshold);
7062 }
7063
7064 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7065 || (changed & WIPHY_PARAM_RETRY_LONG))
7066 {
7067 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7068 wiphy->retry_short :
7069 wiphy->retry_long;
7070
7071 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7072 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 __func__, retry_value);
7076 return -EINVAL;
7077 }
7078
7079 if (changed & WIPHY_PARAM_RETRY_SHORT)
7080 {
7081 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7082 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307083 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307085 hddLog(VOS_TRACE_LEVEL_ERROR,
7086 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 __func__, retry_value);
7088 return -EIO;
7089 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307090 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 __func__, retry_value);
7092 }
7093 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7094 {
7095 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7096 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307097 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307099 hddLog(VOS_TRACE_LEVEL_ERROR,
7100 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 __func__, retry_value);
7102 return -EIO;
7103 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307104 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 __func__, retry_value);
7106 }
7107 }
7108
7109 return 0;
7110}
7111
7112/*
7113 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7114 * This function is used to set the txpower
7115 */
7116static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007117#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7118 struct wireless_dev *wdev,
7119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007120#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307121 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007122#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307123 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007124#endif
7125 int dbm)
7126{
7127 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307128 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7130 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307131 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007132
7133 ENTER();
7134
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307135 status = wlan_hdd_validate_context(pHddCtx);
7136
7137 if (0 != status)
7138 {
7139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7140 "%s: HDD context is not valid", __func__);
7141 return status;
7142 }
7143
7144 hHal = pHddCtx->hHal;
7145
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307146 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7147 dbm, ccmCfgSetCallback,
7148 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307150 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7152 return -EIO;
7153 }
7154
7155 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7156 dbm);
7157
7158 switch(type)
7159 {
7160 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7161 /* Fall through */
7162 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7163 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7166 __func__);
7167 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 }
7169 break;
7170 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007172 __func__);
7173 return -EOPNOTSUPP;
7174 break;
7175 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7177 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007178 return -EIO;
7179 }
7180
7181 return 0;
7182}
7183
7184/*
7185 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7186 * This function is used to read the txpower
7187 */
Yue Maf49ba872013-08-19 12:04:25 -07007188static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7189#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7190 struct wireless_dev *wdev,
7191#endif
7192 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007193{
7194
7195 hdd_adapter_t *pAdapter;
7196 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307197 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007198
Jeff Johnsone7245742012-09-05 17:12:55 -07007199 ENTER();
7200
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307201 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007202
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307203 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007204 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7206 "%s: HDD context is not valid", __func__);
7207 *dbm = 0;
7208 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007209 }
7210
Jeff Johnson295189b2012-06-20 16:38:30 -07007211 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7212 if (NULL == pAdapter)
7213 {
7214 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7215 return -ENOENT;
7216 }
7217
7218 wlan_hdd_get_classAstats(pAdapter);
7219 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7220
Jeff Johnsone7245742012-09-05 17:12:55 -07007221 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 return 0;
7223}
7224
7225static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7226 u8* mac, struct station_info *sinfo)
7227{
7228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7229 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7230 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7231 tANI_U8 rate_flags;
7232
7233 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7234 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007235
7236 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7237 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7238 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7239 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7240 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7241 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7242 tANI_U16 maxRate = 0;
7243 tANI_U16 myRate;
7244 tANI_U16 currentRate = 0;
7245 tANI_U8 maxSpeedMCS = 0;
7246 tANI_U8 maxMCSIdx = 0;
7247 tANI_U8 rateFlag = 1;
7248 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007249 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307250 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007251
Leo Chang6f8870f2013-03-26 18:11:36 -07007252#ifdef WLAN_FEATURE_11AC
7253 tANI_U32 vht_mcs_map;
7254 eDataRate11ACMaxMcs vhtMaxMcs;
7255#endif /* WLAN_FEATURE_11AC */
7256
Jeff Johnsone7245742012-09-05 17:12:55 -07007257 ENTER();
7258
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7260 (0 == ssidlen))
7261 {
7262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7263 " Invalid ssidlen, %d", __func__, ssidlen);
7264 /*To keep GUI happy*/
7265 return 0;
7266 }
7267
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307268 status = wlan_hdd_validate_context(pHddCtx);
7269
7270 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007271 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7273 "%s: HDD context is not valid", __func__);
7274 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007275 }
7276
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007277 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7279
Kiet Lam3b17fc82013-09-27 05:24:08 +05307280 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7281 sinfo->filled |= STATION_INFO_SIGNAL;
7282
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 //convert to the UI units of 100kbps
7284 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7285
7286#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007287 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 -07007288 sinfo->signal,
7289 pCfg->reportMaxLinkSpeed,
7290 myRate,
7291 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007292 (int) pCfg->linkSpeedRssiMid,
7293 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007294 (int) rate_flags,
7295 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007296#endif //LINKSPEED_DEBUG_ENABLED
7297
7298 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7299 {
7300 // we do not want to necessarily report the current speed
7301 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7302 {
7303 // report the max possible speed
7304 rssidx = 0;
7305 }
7306 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7307 {
7308 // report the max possible speed with RSSI scaling
7309 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7310 {
7311 // report the max possible speed
7312 rssidx = 0;
7313 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007314 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 {
7316 // report middle speed
7317 rssidx = 1;
7318 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007319 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7320 {
7321 // report middle speed
7322 rssidx = 2;
7323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 else
7325 {
7326 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007327 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 }
7329 }
7330 else
7331 {
7332 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7333 hddLog(VOS_TRACE_LEVEL_ERROR,
7334 "%s: Invalid value for reportMaxLinkSpeed: %u",
7335 __func__, pCfg->reportMaxLinkSpeed);
7336 rssidx = 0;
7337 }
7338
7339 maxRate = 0;
7340
7341 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307342 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7343 OperationalRates, &ORLeng))
7344 {
7345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7346 /*To keep GUI happy*/
7347 return 0;
7348 }
7349
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 for (i = 0; i < ORLeng; i++)
7351 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007352 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 {
7354 /* Validate Rate Set */
7355 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7356 {
7357 currentRate = supported_data_rate[j].supported_rate[rssidx];
7358 break;
7359 }
7360 }
7361 /* Update MAX rate */
7362 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7363 }
7364
7365 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307366 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7367 ExtendedRates, &ERLeng))
7368 {
7369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7370 /*To keep GUI happy*/
7371 return 0;
7372 }
7373
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 for (i = 0; i < ERLeng; i++)
7375 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007376 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 {
7378 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7379 {
7380 currentRate = supported_data_rate[j].supported_rate[rssidx];
7381 break;
7382 }
7383 }
7384 /* Update MAX rate */
7385 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7386 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307387 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307388 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307389 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307390 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307391 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307393 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7394 MCSRates, &MCSLeng))
7395 {
7396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7397 /*To keep GUI happy*/
7398 return 0;
7399 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007401#ifdef WLAN_FEATURE_11AC
7402 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307403 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007405 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307406 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007407 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007408 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007409 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007411 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007413 maxMCSIdx = 7;
7414 }
7415 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7416 {
7417 maxMCSIdx = 8;
7418 }
7419 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7420 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307421 //VHT20 is supporting 0~8
7422 if (rate_flags & eHAL_TX_RATE_VHT20)
7423 maxMCSIdx = 8;
7424 else
7425 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007426 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307427
7428 if (rate_flags & eHAL_TX_RATE_VHT80)
7429 {
7430 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7431 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7432 }
7433 else if (rate_flags & eHAL_TX_RATE_VHT40)
7434 {
7435 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7436 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7437 }
7438 else if (rate_flags & eHAL_TX_RATE_VHT20)
7439 {
7440 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7441 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7442 }
7443
Leo Chang6f8870f2013-03-26 18:11:36 -07007444 maxSpeedMCS = 1;
7445 if (currentRate > maxRate)
7446 {
7447 maxRate = currentRate;
7448 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307449
Leo Chang6f8870f2013-03-26 18:11:36 -07007450 }
7451 else
7452#endif /* WLAN_FEATURE_11AC */
7453 {
7454 if (rate_flags & eHAL_TX_RATE_HT40)
7455 {
7456 rateFlag |= 1;
7457 }
7458 if (rate_flags & eHAL_TX_RATE_SGI)
7459 {
7460 rateFlag |= 2;
7461 }
7462
7463 for (i = 0; i < MCSLeng; i++)
7464 {
7465 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7466 for (j = 0; j < temp; j++)
7467 {
7468 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7469 {
7470 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7471 break;
7472 }
7473 }
7474 if ((j < temp) && (currentRate > maxRate))
7475 {
7476 maxRate = currentRate;
7477 maxSpeedMCS = 1;
7478 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 }
7481 }
7482 }
7483
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307484 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7485 {
7486 maxRate = myRate;
7487 maxSpeedMCS = 1;
7488 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7489 }
7490
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007492 if (((maxRate < myRate) && (0 == rssidx)) ||
7493 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 {
7495 maxRate = myRate;
7496 if (rate_flags & eHAL_TX_RATE_LEGACY)
7497 {
7498 maxSpeedMCS = 0;
7499 }
7500 else
7501 {
7502 maxSpeedMCS = 1;
7503 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7504 }
7505 }
7506
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307507 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 {
7509 sinfo->txrate.legacy = maxRate;
7510#ifdef LINKSPEED_DEBUG_ENABLED
7511 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7512#endif //LINKSPEED_DEBUG_ENABLED
7513 }
7514 else
7515 {
7516 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007517#ifdef WLAN_FEATURE_11AC
7518 sinfo->txrate.nss = 1;
7519 if (rate_flags & eHAL_TX_RATE_VHT80)
7520 {
7521 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307522 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007523 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307524 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007525 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307526 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7527 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7528 }
7529 else if (rate_flags & eHAL_TX_RATE_VHT20)
7530 {
7531 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7532 }
7533#endif /* WLAN_FEATURE_11AC */
7534 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7535 {
7536 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7537 if (rate_flags & eHAL_TX_RATE_HT40)
7538 {
7539 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7540 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 if (rate_flags & eHAL_TX_RATE_SGI)
7543 {
7544 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7545 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307546
Jeff Johnson295189b2012-06-20 16:38:30 -07007547#ifdef LINKSPEED_DEBUG_ENABLED
7548 pr_info("Reporting MCS rate %d flags %x\n",
7549 sinfo->txrate.mcs,
7550 sinfo->txrate.flags );
7551#endif //LINKSPEED_DEBUG_ENABLED
7552 }
7553 }
7554 else
7555 {
7556 // report current rate instead of max rate
7557
7558 if (rate_flags & eHAL_TX_RATE_LEGACY)
7559 {
7560 //provide to the UI in units of 100kbps
7561 sinfo->txrate.legacy = myRate;
7562#ifdef LINKSPEED_DEBUG_ENABLED
7563 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7564#endif //LINKSPEED_DEBUG_ENABLED
7565 }
7566 else
7567 {
7568 //must be MCS
7569 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007570#ifdef WLAN_FEATURE_11AC
7571 sinfo->txrate.nss = 1;
7572 if (rate_flags & eHAL_TX_RATE_VHT80)
7573 {
7574 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7575 }
7576 else
7577#endif /* WLAN_FEATURE_11AC */
7578 {
7579 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 if (rate_flags & eHAL_TX_RATE_SGI)
7582 {
7583 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7584 }
7585 if (rate_flags & eHAL_TX_RATE_HT40)
7586 {
7587 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7588 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007589#ifdef WLAN_FEATURE_11AC
7590 else if (rate_flags & eHAL_TX_RATE_VHT80)
7591 {
7592 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7593 }
7594#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007595#ifdef LINKSPEED_DEBUG_ENABLED
7596 pr_info("Reporting actual MCS rate %d flags %x\n",
7597 sinfo->txrate.mcs,
7598 sinfo->txrate.flags );
7599#endif //LINKSPEED_DEBUG_ENABLED
7600 }
7601 }
7602 sinfo->filled |= STATION_INFO_TX_BITRATE;
7603
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007604 sinfo->tx_packets =
7605 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7606 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7607 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7608 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7609
7610 sinfo->tx_retries =
7611 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7612 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7613 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7614 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7615
7616 sinfo->tx_failed =
7617 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7618 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7619 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7620 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7621
7622 sinfo->filled |=
7623 STATION_INFO_TX_PACKETS |
7624 STATION_INFO_TX_RETRIES |
7625 STATION_INFO_TX_FAILED;
7626
7627 EXIT();
7628 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007629}
7630
7631static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007632 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007633{
7634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307635 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307637 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007638
Jeff Johnsone7245742012-09-05 17:12:55 -07007639 ENTER();
7640
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 if (NULL == pAdapter)
7642 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 return -ENODEV;
7645 }
7646
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307647 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307648 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307649
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307650 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307651 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7653 "%s: HDD context is not valid", __func__);
7654 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307655 }
7656
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307657 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7658 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7659 (pHddCtx->cfg_ini->fhostArpOffload) &&
7660 (eConnectionState_Associated ==
7661 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7662 {
Amar Singhald53568e2013-09-26 11:03:45 -07007663
7664 hddLog(VOS_TRACE_LEVEL_INFO,
7665 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307666 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307667 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7668 {
7669 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007670 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307671 __func__, vos_status);
7672 }
7673 }
7674
Jeff Johnson295189b2012-06-20 16:38:30 -07007675 /**The get power cmd from the supplicant gets updated by the nl only
7676 *on successful execution of the function call
7677 *we are oppositely mapped w.r.t mode in the driver
7678 **/
7679 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7680
Jeff Johnsone7245742012-09-05 17:12:55 -07007681 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007682 if (VOS_STATUS_E_FAILURE == vos_status)
7683 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7685 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007686 return -EINVAL;
7687 }
7688 return 0;
7689}
7690
7691
7692#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7693static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7694 struct net_device *netdev,
7695 u8 key_index)
7696{
Jeff Johnsone7245742012-09-05 17:12:55 -07007697 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 return 0;
7699}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307700#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007701
7702#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7703static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7704 struct net_device *dev,
7705 struct ieee80211_txq_params *params)
7706{
Jeff Johnsone7245742012-09-05 17:12:55 -07007707 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 return 0;
7709}
7710#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7711static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7712 struct ieee80211_txq_params *params)
7713{
Jeff Johnsone7245742012-09-05 17:12:55 -07007714 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 return 0;
7716}
7717#endif //LINUX_VERSION_CODE
7718
7719static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7720 struct net_device *dev, u8 *mac)
7721{
7722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307723 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007724 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307725 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007726 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007727
Jeff Johnsone7245742012-09-05 17:12:55 -07007728 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307729 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007730 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007732 return -EINVAL;
7733 }
7734
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307735 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7736 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007737
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307738 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007739 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7741 "%s: HDD context is not valid", __func__);
7742 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007743 }
7744
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007746 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 )
7748 {
7749 if( NULL == mac )
7750 {
7751 v_U16_t i;
7752 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7753 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007754 if ((pAdapter->aStaInfo[i].isUsed) &&
7755 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 {
7757 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7758 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007759 "%s: Delete STA with MAC::"
7760 MAC_ADDRESS_STR,
7761 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007762 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7763 if (VOS_IS_STATUS_SUCCESS(vos_status))
7764 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 }
7766 }
7767 }
7768 else
7769 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007770
7771 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7772 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7773 {
7774 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007775 "%s: Skip this DEL STA as this is not used::"
7776 MAC_ADDRESS_STR,
7777 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007778 return -ENOENT;
7779 }
7780
7781 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7782 {
7783 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007784 "%s: Skip this DEL STA as deauth is in progress::"
7785 MAC_ADDRESS_STR,
7786 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007787 return -ENOENT;
7788 }
7789
7790 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7791
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 hddLog(VOS_TRACE_LEVEL_INFO,
7793 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007794 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007796 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007797
7798 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7799 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7800 {
7801 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7802 hddLog(VOS_TRACE_LEVEL_INFO,
7803 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007804 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007805 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007806 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007807 return -ENOENT;
7808 }
7809
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 }
7811 }
7812
7813 EXIT();
7814
7815 return 0;
7816}
7817
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007818static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7819 struct net_device *dev, u8 *mac, struct station_parameters *params)
7820{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007821 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007822#ifdef FEATURE_WLAN_TDLS
7823 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007824 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007825 mask = params->sta_flags_mask;
7826
7827 set = params->sta_flags_set;
7828
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007829#ifdef WLAN_FEATURE_TDLS_DEBUG
7830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7831 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7832 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7833#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007834
7835 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7836 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007837 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007838 }
7839 }
7840#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007841 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007842}
7843
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007844
7845#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007846#define MAX_PMKSAIDS_IN_CACHE 8
7847
7848static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7849static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7850
7851
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007852static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007853 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007854{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307855 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7857 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307858 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307859 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007860 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307861 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307862
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007863 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
7864 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07007865
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307866 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307867 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007868 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007870 return -EINVAL;
7871 }
7872
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307873 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7874 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007875
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307876 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007877 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7879 "%s: HDD context is not valid", __func__);
7880 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007881 }
7882
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307883 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007884 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7885
Wilson Yang6507c4e2013-10-01 20:11:19 -07007886 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307888 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007889 pmksa->bssid, WNI_CFG_BSSID_LEN))
7890 {
7891 /* BSSID matched previous entry. Overwrite it. */
7892 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307893 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007894 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307895 vos_mem_copy(PMKIDCache[j].PMKID,
7896 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007897 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307898 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007899 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900 dump_bssid(pmksa->bssid);
7901 dump_pmkid(halHandle, pmksa->pmkid);
7902 break;
7903 }
7904 }
7905
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007906 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07007907 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007908
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007909 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307910 {
7911 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07007912 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307913 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007914 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307915 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007916 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007918 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007919 dump_bssid(pmksa->bssid);
7920 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307921 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007922 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07007923 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007924 }
7925
7926
7927 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307928 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007929 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307930 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007931 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007932 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307933 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7934 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007935 PMKIDCacheIndex);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007936 return 0;
7937}
7938
7939
Wilson Yang6507c4e2013-10-01 20:11:19 -07007940
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007941static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007942 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007943{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007944 tANI_U32 j=0;
7945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7946 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007947 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007948 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08007949 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007950
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007951 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
7952 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007953
7954 /* Validate pAdapter */
7955 if (NULL == pAdapter)
7956 {
7957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
7958 return -EINVAL;
7959 }
7960
7961 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7962 status = wlan_hdd_validate_context(pHddCtx);
7963
7964 if (0 != status)
7965 {
7966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7967 "%s: HDD context is not valid", __func__);
7968 return status;
7969 }
7970
7971 /*Retrieve halHandle*/
7972 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7973
7974 /*in case index is 0,no entry to delete*/
7975 if (0 == PMKIDCacheIndex)
7976 {
7977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7978 __func__);
7979 return -EINVAL;
7980 }
7981
7982 /*find the matching PMKSA entry from j=0 to (index-1),
7983 * and delete the matched one
7984 */
7985 for (j = 0; j<PMKIDCacheIndex; j++)
7986 {
7987 if (vos_mem_compare(PMKIDCache[j].BSSID,
7988 pmksa->bssid,
7989 WNI_CFG_BSSID_LEN))
7990 {
7991 /* BSSID matched entry */
7992 BSSIDMatched = 1;
7993
7994 if (j<PMKIDCacheIndex-1)
7995 {
7996 /*replace the matching entry with the last entry in HDD local cache*/
7997 vos_mem_copy(PMKIDCache[j].BSSID,
7998 PMKIDCache[PMKIDCacheIndex-1].BSSID,
7999 WNI_CFG_BSSID_LEN);
8000 vos_mem_copy(PMKIDCache[j].PMKID,
8001 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8002 CSR_RSN_PMKID_SIZE);
8003 }
8004
8005 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008006 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8007 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8008
8009 /*reduce the PMKID array index*/
8010 PMKIDCacheIndex--;
8011
8012 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008013 if (eHAL_STATUS_SUCCESS !=
8014 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008015 {
8016 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8017 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008018 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008019 }
8020
8021 dump_bssid(pmksa->bssid);
8022 dump_pmkid(halHandle,pmksa->pmkid);
8023
8024 break;
8025 }
8026 }
8027
8028 /* we compare all entries,but cannot find matching entry */
8029 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8030 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008031 hddLog(VOS_TRACE_LEVEL_FATAL,
8032 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8033 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008034 dump_bssid(pmksa->bssid);
8035 dump_pmkid(halHandle, pmksa->pmkid);
8036 return -EINVAL;
8037 }
Wilson Yangef657d32014-01-15 19:19:23 -08008038 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008039}
8040
Wilson Yang6507c4e2013-10-01 20:11:19 -07008041
8042
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008043static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8044{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008045 tANI_U32 j=0;
8046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8047 tHalHandle halHandle;
8048 hdd_context_t *pHddCtx;
8049 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008050 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008051
8052 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8053
8054 /* Validate pAdapter */
8055 if (NULL == pAdapter)
8056 {
8057 hddLog(VOS_TRACE_LEVEL_ERROR,
8058 "%s: Invalid Adapter" ,__func__);
8059 return -EINVAL;
8060 }
8061
8062 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8063 status = wlan_hdd_validate_context(pHddCtx);
8064
8065 if (0 != status)
8066 {
8067 hddLog(VOS_TRACE_LEVEL_ERROR,
8068 "%s: HDD context is not valid", __func__);
8069 return status;
8070 }
8071
8072 /*Retrieve halHandle*/
8073 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8074
8075 /*in case index is 0,no entry to delete*/
8076 if (0 == PMKIDCacheIndex)
8077 {
8078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8079 __func__);
8080 return -EINVAL;
8081 }
8082
8083 /*delete all the PMKSA one by one */
8084 for (j = 0; j<PMKIDCacheIndex; j++)
8085 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008086 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008087
8088 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008089 if (eHAL_STATUS_SUCCESS !=
8090 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008091 {
8092 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8093 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008094 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008095 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308096 /*clear the entry in HDD cache 0--index-1 */
8097 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8098 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008099 }
8100
8101 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008102 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008103}
8104#endif
8105
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008106#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308107static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008108 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8109{
8110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8111 hdd_station_ctx_t *pHddStaCtx;
8112
8113 if (NULL == pAdapter)
8114 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008116 return -ENODEV;
8117 }
8118
8119 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8120
8121 // Added for debug on reception of Re-assoc Req.
8122 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8123 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008124 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008125 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008126 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008127 }
8128
8129#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008130 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008131 ftie->ie_len);
8132#endif
8133
8134 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308135 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8136 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008137 ftie->ie_len);
8138 return 0;
8139}
8140#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008141
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308142#ifdef FEATURE_WLAN_SCAN_PNO
8143
8144void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8145 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8146{
8147 int ret;
8148 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8149 hdd_context_t *pHddCtx;
8150
Nirav Shah80830bf2013-12-31 16:35:12 +05308151 ENTER();
8152
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308153 if (NULL == pAdapter)
8154 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308156 "%s: HDD adapter is Null", __func__);
8157 return ;
8158 }
8159
8160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8161 if (NULL == pHddCtx)
8162 {
8163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8164 "%s: HDD context is Null!!!", __func__);
8165 return ;
8166 }
8167
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308168 spin_lock(&pHddCtx->schedScan_lock);
8169 if (TRUE == pHddCtx->isWiphySuspended)
8170 {
8171 pHddCtx->isSchedScanUpdatePending = TRUE;
8172 spin_unlock(&pHddCtx->schedScan_lock);
8173 hddLog(VOS_TRACE_LEVEL_INFO,
8174 "%s: Update cfg80211 scan database after it resume", __func__);
8175 return ;
8176 }
8177 spin_unlock(&pHddCtx->schedScan_lock);
8178
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308179 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8180
8181 if (0 > ret)
8182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8183
8184 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8186 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308187}
8188
8189/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308190 * FUNCTION: wlan_hdd_is_pno_allowed
8191 * To check is there any P2P GO/SAP or P2P Client/STA
8192 * session is active
8193 */
8194static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8195{
8196 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8197 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308198 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308199 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8200 int status = 0;
8201 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8202
8203 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8204 {
8205 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308206 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308207
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308208 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8209 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8210 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8211 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8212 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8213 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308214 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308215 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308216 }
8217 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8218 pAdapterNode = pNext;
8219 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308220 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308221}
8222
8223/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308224 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8225 * NL interface to enable PNO
8226 */
8227static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8228 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8229{
8230 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8231 tpSirPNOScanReq pPnoRequest = NULL;
8232 hdd_context_t *pHddCtx;
8233 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308234 v_U32_t i, indx, num_ch, tempInterval;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308235 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8236 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8237 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8238 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308239 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308240
8241 if (NULL == pAdapter)
8242 {
8243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8244 "%s: HDD adapter is Null", __func__);
8245 return -ENODEV;
8246 }
8247
8248 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308249 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308250
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308251 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308252 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8254 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308255 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308256 }
8257
8258 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8259 if (NULL == hHal)
8260 {
8261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8262 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308263 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308264 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308265
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308266 /* The current firmware design for PNO does not consider concurrent
8267 * active sessions.Hence , determine the concurrent active sessions
8268 * and return a failure to the framework on a request for schedule
8269 * scan.
8270 */
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308271 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308272 {
8273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308274 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308275 return -EBUSY;
8276 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308277
8278 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8279 if (NULL == pPnoRequest)
8280 {
8281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8282 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308283 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308284 }
8285
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308286 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308287 pPnoRequest->enable = 1; /*Enable PNO */
8288 pPnoRequest->ucNetworksCount = request->n_match_sets;
8289
8290 if (( !pPnoRequest->ucNetworksCount ) ||
8291 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8292 {
8293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308294 "%s: Network input is not correct %d",
8295 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308296 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308297 goto error;
8298 }
8299
8300 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8301 {
8302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308303 "%s: Incorrect number of channels %d",
8304 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308305 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308306 goto error;
8307 }
8308
8309 /* Framework provides one set of channels(all)
8310 * common for all saved profile */
8311 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8312 channels_allowed, &num_channels_allowed))
8313 {
8314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8315 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308316 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308317 goto error;
8318 }
8319 /* Checking each channel against allowed channel list */
8320 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308321 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308322 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308323 char chList [(request->n_channels*5)+1];
8324 int len;
8325 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308326 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308327 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308328 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308329 if (request->channels[i]->hw_value == channels_allowed[indx])
8330 {
8331 valid_ch[num_ch++] = request->channels[i]->hw_value;
8332 len += snprintf(chList+len, 5, "%d ",
8333 request->channels[i]->hw_value);
8334 break ;
8335 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308336 }
8337 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308338 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8339 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308340
8341 /* Filling per profile params */
8342 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8343 {
8344 pPnoRequest->aNetworks[i].ssId.length =
8345 request->match_sets[i].ssid.ssid_len;
8346
8347 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8348 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8349 {
8350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308351 "%s: SSID Len %d is not correct for network %d",
8352 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308353 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308354 goto error;
8355 }
8356
8357 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8358 request->match_sets[i].ssid.ssid,
8359 request->match_sets[i].ssid.ssid_len);
8360 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8361 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8362 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8363
8364 /*Copying list of valid channel into request */
8365 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8366 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8367
8368 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8369 }
8370
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008372 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308373 if ((0 < request->ie_len) && (NULL != request->ie))
8374 {
8375 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8376 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8377 pPnoRequest->us24GProbeTemplateLen);
8378
8379 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8380 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8381 pPnoRequest->us5GProbeTemplateLen);
8382 }
8383
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308384 /* Driver gets only one time interval which is hardcoded in
8385 * supplicant for 10000ms. Taking power consumption into account 6 timers
8386 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8387 * 80,160,320 secs. And number of scan cycle for each timer
8388 * is configurable through INI param gPNOScanTimerRepeatValue.
8389 * If it is set to 0 only one timer will be used and PNO scan cycle
8390 * will be repeated after each interval specified by supplicant
8391 * till PNO is disabled.
8392 */
8393 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8394 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8395 else
8396 pPnoRequest->scanTimers.ucScanTimersCount =
8397 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8398
8399 tempInterval = (request->interval)/1000;
8400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8401 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8402 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8403 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8404 {
8405 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8406 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8407 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8408 tempInterval *= 2;
8409 }
8410 //Repeat last timer until pno disabled.
8411 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8412
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308413 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308414
Nirav Shah80830bf2013-12-31 16:35:12 +05308415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8416 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8417 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8418 pPnoRequest->scanTimers.ucScanTimersCount);
8419
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308420 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8421 pPnoRequest, pAdapter->sessionId,
8422 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8423 if (eHAL_STATUS_SUCCESS != status)
8424 {
8425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308426 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308427 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308428 goto error;
8429 }
8430
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8432 "PNO scanRequest offloaded");
8433
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308434error:
8435 vos_mem_free(pPnoRequest);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308436 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308437}
8438
8439/*
8440 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8441 * NL interface to disable PNO
8442 */
8443static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8444 struct net_device *dev)
8445{
8446 eHalStatus status = eHAL_STATUS_FAILURE;
8447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8448 hdd_context_t *pHddCtx;
8449 tHalHandle hHal;
8450 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308451 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308452
8453 ENTER();
8454
8455 if (NULL == pAdapter)
8456 {
8457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8458 "%s: HDD adapter is Null", __func__);
8459 return -ENODEV;
8460 }
8461
8462 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308463
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308464 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308465 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308467 "%s: HDD context is Null", __func__);
8468 return -ENODEV;
8469 }
8470
8471 /* The return 0 is intentional when isLogpInProgress and
8472 * isLoadUnloadInProgress. We did observe a crash due to a return of
8473 * failure in sched_scan_stop , especially for a case where the unload
8474 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8475 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8476 * success. If it returns a failure , then its next invocation due to the
8477 * clean up of the second interface will have the dev pointer corresponding
8478 * to the first one leading to a crash.
8479 */
8480 if (pHddCtx->isLogpInProgress)
8481 {
8482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8483 "%s: LOGP in Progress. Ignore!!!", __func__);
8484 return ret;
8485 }
8486
8487 if (pHddCtx->isLoadUnloadInProgress)
8488 {
8489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8490 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8491 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308492 }
8493
8494 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8495 if (NULL == hHal)
8496 {
8497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8498 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308499 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308500 }
8501
8502 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8503 if (NULL == pPnoRequest)
8504 {
8505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8506 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308507 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308508 }
8509
8510 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8511 pPnoRequest->enable = 0; /* Disable PNO */
8512 pPnoRequest->ucNetworksCount = 0;
8513
8514 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8515 pAdapter->sessionId,
8516 NULL, pAdapter);
8517 if (eHAL_STATUS_SUCCESS != status)
8518 {
8519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8520 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308521 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308522 }
8523
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8525 "%s: PNO scan disabled", __func__);
8526
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308527 vos_mem_free(pPnoRequest);
8528
8529 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308530 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308531}
8532
8533#endif /*FEATURE_WLAN_SCAN_PNO*/
8534
8535
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008536#ifdef FEATURE_WLAN_TDLS
8537static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8538 u8 *peer, u8 action_code, u8 dialog_token,
8539 u16 status_code, const u8 *buf, size_t len)
8540{
8541
8542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8543 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008544 u8 peerMac[6];
8545 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008546 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008547 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008548 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008549
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008550 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008553 "Invalid arguments");
8554 return -EINVAL;
8555 }
8556
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008557 if (pHddCtx->isLogpInProgress)
8558 {
8559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8560 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008561 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008562 return -EBUSY;
8563 }
8564
Hoonki Lee27511902013-03-14 18:19:06 -07008565 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008566 {
Hoonki Lee27511902013-03-14 18:19:06 -07008567 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8568 "%s: TDLS mode is disabled OR not enabled in FW."
8569 MAC_ADDRESS_STR " action %d declined.",
8570 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008571 return -ENOTSUPP;
8572 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008573
Hoonki Lee27511902013-03-14 18:19:06 -07008574 /* other than teardown frame, other mgmt frames are not sent if disabled */
8575 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8576 {
8577 /* if tdls_mode is disabled to respond to peer's request */
8578 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8579 {
8580 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8581 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008582 " TDLS mode is disabled. action %d declined.",
8583 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008584
8585 return -ENOTSUPP;
8586 }
8587 }
8588
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008589 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8590 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308591 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008592 {
8593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008594 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008595 " TDLS setup is ongoing. action %d declined.",
8596 __func__, MAC_ADDR_ARRAY(peer), action_code);
8597 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008598 }
8599 }
8600
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008601 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8602 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008603 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008604 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008605 {
8606 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8607 we return error code at 'add_station()'. Hence we have this
8608 check again in addtion to add_station().
8609 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008610 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008611 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8613 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008614 " TDLS Max peer already connected. action %d declined.",
8615 __func__, MAC_ADDR_ARRAY(peer), action_code);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308616 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008617 }
8618 else
8619 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008620 /* maximum reached. tweak to send error code to peer and return
8621 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008622 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8624 "%s: " MAC_ADDRESS_STR
8625 " TDLS Max peer already connected send response status %d",
8626 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008627 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008628 /* fall through to send setup resp with failure status
8629 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008630 }
8631 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008632 else
8633 {
8634 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308635 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008636 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008637 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008639 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8640 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008641 return -EPERM;
8642 }
8643 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008644 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008645 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008646
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008647#ifdef WLAN_FEATURE_TDLS_DEBUG
8648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008649 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
8650 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8651 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008652#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008653
Hoonki Leea34dd892013-02-05 22:56:02 -08008654 /*Except teardown responder will not be used so just make 0*/
8655 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008656 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008657 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008658
8659 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308660 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008661
8662 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8663 responder = pTdlsPeer->is_responder;
8664 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008665 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8667 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
8668 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8669 dialog_token, status_code, len);
8670 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008671 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008672 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008673
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308674 /* For explicit trigger of DIS_REQ come out of BMPS for
8675 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008676 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308677 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8678 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008679 {
8680 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8681 {
8682 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308683 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008684 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8685 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308686 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8687 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008688 }
8689
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008690 /* make sure doesn't call send_mgmt() while it is pending */
8691 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8692 {
8693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008694 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008695 __func__, MAC_ADDR_ARRAY(peer), action_code);
8696 return -EBUSY;
8697 }
8698
8699 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008700 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8701
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008702 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08008703 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008704
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008705 if (VOS_STATUS_SUCCESS != status)
8706 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8708 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008709 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008710 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308711 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008712 }
8713
Hoonki Leed37cbb32013-04-20 00:31:14 -07008714 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8715 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8716
8717 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008718 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008720 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008721 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008722 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008723
8724 if (pHddCtx->isLogpInProgress)
8725 {
8726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8727 "%s: LOGP in Progress. Ignore!!!", __func__);
8728 return -EAGAIN;
8729 }
8730
Hoonki Leed37cbb32013-04-20 00:31:14 -07008731 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308732 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008733 }
8734
Gopichand Nakkala05922802013-03-14 12:23:19 -07008735 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008736 {
8737 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008738 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008739 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008740
Hoonki Leea34dd892013-02-05 22:56:02 -08008741 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8742 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008743 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008744 }
8745 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8746 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008747 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008748 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008749
8750 return 0;
8751}
8752
8753static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8754 u8 *peer, enum nl80211_tdls_operation oper)
8755{
8756 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8757 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308758 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008759 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008760
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308761 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008762 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008764 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008765 return -EINVAL;
8766 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008767
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308768 status = wlan_hdd_validate_context(pHddCtx);
8769
8770 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008771 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8773 "%s: HDD context is not valid", __func__);
8774 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008775 }
8776
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008777
8778 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008779 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008780 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008782 "TDLS Disabled in INI OR not enabled in FW. "
8783 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008784 return -ENOTSUPP;
8785 }
8786
8787 switch (oper) {
8788 case NL80211_TDLS_ENABLE_LINK:
8789 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008790 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308791 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308792 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008793
Sunil Dutt41de4e22013-11-14 18:09:02 +05308794 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8795
8796 if ( NULL == pTdlsPeer ) {
8797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8798 " (oper %d) not exsting. ignored",
8799 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8800 return -EINVAL;
8801 }
8802
8803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8804 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8805 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8806 "NL80211_TDLS_ENABLE_LINK");
8807
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07008808 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
8809 {
8810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
8811 MAC_ADDRESS_STR " failed",
8812 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
8813 return -EINVAL;
8814 }
8815
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008816 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008817 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308818 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05308819
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308820 if (0 != wlan_hdd_tdls_get_link_establish_params(
8821 pAdapter, peer,&tdlsLinkEstablishParams)) {
8822 return -EINVAL;
8823 }
8824 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308825
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308826 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
8827 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
8828 /* Send TDLS peer UAPSD capabilities to the firmware and
8829 * register with the TL on after the response for this operation
8830 * is received .
8831 */
8832 ret = wait_for_completion_interruptible_timeout(
8833 &pAdapter->tdls_link_establish_req_comp,
8834 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
8835 if (ret <= 0)
8836 {
8837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8838 "%s: Link Establish Request Faled Status %ld",
8839 __func__, ret);
8840 return -EINVAL;
8841 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308842 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008843 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05308844 /* Mark TDLS client Authenticated .*/
8845 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
8846 pTdlsPeer->staId,
8847 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008848 if (VOS_STATUS_SUCCESS == status)
8849 {
Hoonki Lee14621352013-04-16 17:51:19 -07008850 if (pTdlsPeer->is_responder == 0)
8851 {
8852 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
8853
8854 wlan_hdd_tdls_timer_restart(pAdapter,
8855 &pTdlsPeer->initiatorWaitTimeoutTimer,
8856 WAIT_TIME_TDLS_INITIATOR);
8857 /* suspend initiator TX until it receives direct packet from the
8858 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
8859 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8860 &staId, NULL);
8861 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008862 wlan_hdd_tdls_increment_peer_count(pAdapter);
8863 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008864 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308865
8866 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308867 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
8868 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308869 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308870 int ac;
8871 uint8 ucAc[4] = { WLANTL_AC_VO,
8872 WLANTL_AC_VI,
8873 WLANTL_AC_BK,
8874 WLANTL_AC_BE };
8875 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
8876 for(ac=0; ac < 4; ac++)
8877 {
8878 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8879 pTdlsPeer->staId, ucAc[ac],
8880 tlTid[ac], tlTid[ac], 0, 0,
8881 WLANTL_BI_DIR );
8882 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308883 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008884 }
8885
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008886 }
8887 break;
8888 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08008889 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05308890 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8891
8892 if ( NULL == pTdlsPeer ) {
8893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8894 " (oper %d) not exsting. ignored",
8895 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8896 return -EINVAL;
8897 }
8898
8899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8900 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8901 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8902 "NL80211_TDLS_DISABLE_LINK");
8903
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008904 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008905 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008906 long status;
8907
8908 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
8909
Lee Hoonkic1262f22013-01-24 21:59:00 -08008910 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
8911 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008912
8913 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
8914 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
8915 if (status <= 0)
8916 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008917 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8919 "%s: Del station failed status %ld",
8920 __func__, status);
8921 return -EPERM;
8922 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008923 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008924 }
8925 else
8926 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8928 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008929 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008930 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008931 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008932 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308933 {
8934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8935 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
8936 __func__, MAC_ADDR_ARRAY(peer));
8937
8938 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8939 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8940
8941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8942 " %s TDLS External control and Implicit Trigger not enabled ",
8943 __func__);
8944 return -ENOTSUPP;
8945 }
8946
Sunil Dutt41de4e22013-11-14 18:09:02 +05308947
8948 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8949
8950 if ( NULL == pTdlsPeer ) {
8951 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
8952 " peer not exsting",
8953 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308954 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308955 }
8956 else {
8957 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
8958 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
8959 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308960
8961 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
8962 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308963 break;
8964 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008965 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308966 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308967 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8969 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
8970 __func__, MAC_ADDR_ARRAY(peer));
8971
8972 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8973 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8974
8975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8976 " %s TDLS External control and Implicit Trigger not enabled ",
8977 __func__);
8978 return -ENOTSUPP;
8979 }
8980
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308981 /* To cater the requirement of establishing the TDLS link
8982 * irrespective of the data traffic , get an entry of TDLS peer.
8983 */
8984 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
8985 if (pTdlsPeer == NULL) {
8986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8987 "%s: peer " MAC_ADDRESS_STR " not existing",
8988 __func__, MAC_ADDR_ARRAY(peer));
8989 return -EINVAL;
8990 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308991
8992 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
8993
8994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8995 " %s TDLS Add Force Peer Failed",
8996 __func__);
8997 return -EINVAL;
8998 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308999 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309000 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009001 case NL80211_TDLS_DISCOVERY_REQ:
9002 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9004 "%s: We don't support in-driver setup/teardown/discovery "
9005 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009006 return -ENOTSUPP;
9007 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9009 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009010 return -ENOTSUPP;
9011 }
9012 return 0;
9013}
Chilam NG571c65a2013-01-19 12:27:36 +05309014
9015int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9016 struct net_device *dev, u8 *peer)
9017{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009018 hddLog(VOS_TRACE_LEVEL_INFO,
9019 "tdls send discover req: "MAC_ADDRESS_STR,
9020 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309021
9022 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9023 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
9024}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009025#endif
9026
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309027#ifdef WLAN_FEATURE_GTK_OFFLOAD
9028/*
9029 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9030 * Callback rountine called upon receiving response for
9031 * get offload info
9032 */
9033void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9034 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9035{
9036
9037 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309038 tANI_U8 tempReplayCounter[8];
9039 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309040
9041 ENTER();
9042
9043 if (NULL == pAdapter)
9044 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309046 "%s: HDD adapter is Null", __func__);
9047 return ;
9048 }
9049
9050 if (NULL == pGtkOffloadGetInfoRsp)
9051 {
9052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9053 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9054 return ;
9055 }
9056
9057 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9058 {
9059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9060 "%s: wlan Failed to get replay counter value",
9061 __func__);
9062 return ;
9063 }
9064
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309065 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9066 /* Update replay counter */
9067 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9068 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9069
9070 {
9071 /* changing from little to big endian since supplicant
9072 * works on big endian format
9073 */
9074 int i;
9075 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9076
9077 for (i = 0; i < 8; i++)
9078 {
9079 tempReplayCounter[7-i] = (tANI_U8)p[i];
9080 }
9081 }
9082
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309083 /* Update replay counter to NL */
9084 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309085 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309086}
9087
9088/*
9089 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9090 * This function is used to offload GTK rekeying job to the firmware.
9091 */
9092int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9093 struct cfg80211_gtk_rekey_data *data)
9094{
9095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9096 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9097 hdd_station_ctx_t *pHddStaCtx;
9098 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309099 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309100 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309101 eHalStatus status = eHAL_STATUS_FAILURE;
9102
9103 ENTER();
9104
9105 if (NULL == pAdapter)
9106 {
9107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9108 "%s: HDD adapter is Null", __func__);
9109 return -ENODEV;
9110 }
9111
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309112 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309113
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309114 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9117 "%s: HDD context is not valid", __func__);
9118 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309119 }
9120
9121 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9122 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9123 if (NULL == hHal)
9124 {
9125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9126 "%s: HAL context is Null!!!", __func__);
9127 return -EAGAIN;
9128 }
9129
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309130 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9131 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9132 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9133 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309134 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309135 {
9136 /* changing from big to little endian since driver
9137 * works on little endian format
9138 */
9139 tANI_U8 *p =
9140 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9141 int i;
9142
9143 for (i = 0; i < 8; i++)
9144 {
9145 p[7-i] = data->replay_ctr[i];
9146 }
9147 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309148
9149 if (TRUE == pHddCtx->hdd_wlan_suspended)
9150 {
9151 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309152 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9153 sizeof (tSirGtkOffloadParams));
9154 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309155 pAdapter->sessionId);
9156
9157 if (eHAL_STATUS_SUCCESS != status)
9158 {
9159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9160 "%s: sme_SetGTKOffload failed, returned %d",
9161 __func__, status);
9162 return status;
9163 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9165 "%s: sme_SetGTKOffload successfull", __func__);
9166 }
9167 else
9168 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9170 "%s: wlan not suspended GTKOffload request is stored",
9171 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309172 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309173
9174 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309175}
9176#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9177
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309178/*
9179 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9180 * This function is used to set access control policy
9181 */
9182static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9183 struct net_device *dev, const struct cfg80211_acl_data *params)
9184{
9185 int i;
9186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9187 hdd_hostapd_state_t *pHostapdState;
9188 tsap_Config_t *pConfig;
9189 v_CONTEXT_t pVosContext = NULL;
9190 hdd_context_t *pHddCtx;
9191 int status;
9192
9193 ENTER();
9194
9195 if (NULL == pAdapter)
9196 {
9197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9198 "%s: HDD adapter is Null", __func__);
9199 return -ENODEV;
9200 }
9201
9202 if (NULL == params)
9203 {
9204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9205 "%s: params is Null", __func__);
9206 return -EINVAL;
9207 }
9208
9209 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9210 status = wlan_hdd_validate_context(pHddCtx);
9211
9212 if (0 != status)
9213 {
9214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9215 "%s: HDD context is not valid", __func__);
9216 return status;
9217 }
9218
9219 pVosContext = pHddCtx->pvosContext;
9220 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9221
9222 if (NULL == pHostapdState)
9223 {
9224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9225 "%s: pHostapdState is Null", __func__);
9226 return -EINVAL;
9227 }
9228
9229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9230 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9231
9232 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9233 {
9234 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9235
9236 /* default value */
9237 pConfig->num_accept_mac = 0;
9238 pConfig->num_deny_mac = 0;
9239
9240 /**
9241 * access control policy
9242 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9243 * listed in hostapd.deny file.
9244 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9245 * listed in hostapd.accept file.
9246 */
9247 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9248 {
9249 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9250 }
9251 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9252 {
9253 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9254 }
9255 else
9256 {
9257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9258 "%s:Acl Policy : %d is not supported",
9259 __func__, params->acl_policy);
9260 return -ENOTSUPP;
9261 }
9262
9263 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9264 {
9265 pConfig->num_accept_mac = params->n_acl_entries;
9266 for (i = 0; i < params->n_acl_entries; i++)
9267 {
9268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9269 "** Add ACL MAC entry %i in WhiletList :"
9270 MAC_ADDRESS_STR, i,
9271 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9272
9273 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9274 sizeof(qcmacaddr));
9275 }
9276 }
9277 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9278 {
9279 pConfig->num_deny_mac = params->n_acl_entries;
9280 for (i = 0; i < params->n_acl_entries; i++)
9281 {
9282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9283 "** Add ACL MAC entry %i in BlackList :"
9284 MAC_ADDRESS_STR, i,
9285 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9286
9287 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9288 sizeof(qcmacaddr));
9289 }
9290 }
9291
9292 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9293 {
9294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9295 "%s: SAP Set Mac Acl fail", __func__);
9296 return -EINVAL;
9297 }
9298 }
9299 else
9300 {
9301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9302 "%s: Invalid device_mode = %d",
9303 __func__, pAdapter->device_mode);
9304 return -EINVAL;
9305 }
9306
9307 return 0;
9308}
9309
Leo Chang9056f462013-08-01 19:21:11 -07009310#ifdef WLAN_NL80211_TESTMODE
9311#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009312void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009313(
9314 void *pAdapter,
9315 void *indCont
9316)
9317{
Leo Changd9df8aa2013-09-26 13:32:26 -07009318 tSirLPHBInd *lphbInd;
9319 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009320
9321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009322 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009323
9324 if (NULL == indCont)
9325 {
9326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009327 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009328 return;
9329 }
9330
Leo Changd9df8aa2013-09-26 13:32:26 -07009331 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009332 skb = cfg80211_testmode_alloc_event_skb(
9333 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009334 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009335 GFP_ATOMIC);
9336 if (!skb)
9337 {
9338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9339 "LPHB timeout, NL buffer alloc fail");
9340 return;
9341 }
9342
Leo Changac3ba772013-10-07 09:47:04 -07009343 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009344 {
9345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9346 "WLAN_HDD_TM_ATTR_CMD put fail");
9347 goto nla_put_failure;
9348 }
Leo Changac3ba772013-10-07 09:47:04 -07009349 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009350 {
9351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9352 "WLAN_HDD_TM_ATTR_TYPE put fail");
9353 goto nla_put_failure;
9354 }
Leo Changac3ba772013-10-07 09:47:04 -07009355 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009356 sizeof(tSirLPHBInd), lphbInd))
9357 {
9358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9359 "WLAN_HDD_TM_ATTR_DATA put fail");
9360 goto nla_put_failure;
9361 }
Leo Chang9056f462013-08-01 19:21:11 -07009362 cfg80211_testmode_event(skb, GFP_ATOMIC);
9363 return;
9364
9365nla_put_failure:
9366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9367 "NLA Put fail");
9368 kfree_skb(skb);
9369
9370 return;
9371}
9372#endif /* FEATURE_WLAN_LPHB */
9373
9374static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9375{
9376 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9377 int err = 0;
9378#ifdef FEATURE_WLAN_LPHB
9379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009380 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009381#endif /* FEATURE_WLAN_LPHB */
9382
9383 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9384 if (err)
9385 {
9386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9387 "%s Testmode INV ATTR", __func__);
9388 return err;
9389 }
9390
9391 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9392 {
9393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9394 "%s Testmode INV CMD", __func__);
9395 return -EINVAL;
9396 }
9397
9398 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9399 {
9400#ifdef FEATURE_WLAN_LPHB
9401 /* Low Power Heartbeat configuration request */
9402 case WLAN_HDD_TM_CMD_WLAN_HB:
9403 {
9404 int buf_len;
9405 void *buf;
9406 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009407 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009408
9409 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9410 {
9411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9412 "%s Testmode INV DATA", __func__);
9413 return -EINVAL;
9414 }
9415
9416 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9417 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009418
9419 hb_params_temp =(tSirLPHBReq *)buf;
9420 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9421 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9422 return -EINVAL;
9423
Leo Chang9056f462013-08-01 19:21:11 -07009424 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9425 if (NULL == hb_params)
9426 {
9427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9428 "%s Request Buffer Alloc Fail", __func__);
9429 return -EINVAL;
9430 }
9431
9432 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009433 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9434 hb_params,
9435 wlan_hdd_cfg80211_lphb_ind_handler);
9436 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009437 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009440 vos_mem_free(hb_params);
9441 }
Leo Chang9056f462013-08-01 19:21:11 -07009442 return 0;
9443 }
9444#endif /* FEATURE_WLAN_LPHB */
9445 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9447 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009448 return -EOPNOTSUPP;
9449 }
9450
9451 return err;
9452}
9453#endif /* CONFIG_NL80211_TESTMODE */
9454
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309455static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9456 struct net_device *dev,
9457 int idx, struct survey_info *survey)
9458{
9459 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9460 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309461 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309462 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309463 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309464 v_S7_t snr,rssi;
9465 int status, i, j, filled = 0;
9466
9467 ENTER();
9468
9469
9470 if (NULL == pAdapter)
9471 {
9472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9473 "%s: HDD adapter is Null", __func__);
9474 return -ENODEV;
9475 }
9476
9477 if (NULL == wiphy)
9478 {
9479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9480 "%s: wiphy is Null", __func__);
9481 return -ENODEV;
9482 }
9483
9484 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9485 status = wlan_hdd_validate_context(pHddCtx);
9486
9487 if (0 != status)
9488 {
9489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9490 "%s: HDD context is not valid", __func__);
9491 return status;
9492 }
9493
Mihir Sheted9072e02013-08-21 17:02:29 +05309494 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9495
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309496 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309497 0 != pAdapter->survey_idx ||
9498 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309499 {
9500 /* The survey dump ops when implemented completely is expected to
9501 * return a survey of all channels and the ops is called by the
9502 * kernel with incremental values of the argument 'idx' till it
9503 * returns -ENONET. But we can only support the survey for the
9504 * operating channel for now. survey_idx is used to track
9505 * that the ops is called only once and then return -ENONET for
9506 * the next iteration
9507 */
9508 pAdapter->survey_idx = 0;
9509 return -ENONET;
9510 }
9511
9512 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9513
9514 wlan_hdd_get_snr(pAdapter, &snr);
9515 wlan_hdd_get_rssi(pAdapter, &rssi);
9516
9517 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9518 hdd_wlan_get_freq(channel, &freq);
9519
9520
9521 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9522 {
9523 if (NULL == wiphy->bands[i])
9524 {
9525 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9526 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9527 continue;
9528 }
9529
9530 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9531 {
9532 struct ieee80211_supported_band *band = wiphy->bands[i];
9533
9534 if (band->channels[j].center_freq == (v_U16_t)freq)
9535 {
9536 survey->channel = &band->channels[j];
9537 /* The Rx BDs contain SNR values in dB for the received frames
9538 * while the supplicant expects noise. So we calculate and
9539 * return the value of noise (dBm)
9540 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9541 */
9542 survey->noise = rssi - snr;
9543 survey->filled = SURVEY_INFO_NOISE_DBM;
9544 filled = 1;
9545 }
9546 }
9547 }
9548
9549 if (filled)
9550 pAdapter->survey_idx = 1;
9551 else
9552 {
9553 pAdapter->survey_idx = 0;
9554 return -ENONET;
9555 }
9556
9557 return 0;
9558}
9559
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309560/*
9561 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9562 * this is called when cfg80211 driver resume
9563 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9564 */
9565int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9566{
9567 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9568 hdd_adapter_t *pAdapter;
9569 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9570 VOS_STATUS status = VOS_STATUS_SUCCESS;
9571
9572 ENTER();
9573
9574 if ( NULL == pHddCtx )
9575 {
9576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9577 "%s: HddCtx validation failed", __func__);
9578 return 0;
9579 }
9580
9581 if (pHddCtx->isLogpInProgress)
9582 {
9583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9584 "%s: LOGP in Progress. Ignore!!!", __func__);
9585 return 0;
9586 }
9587
9588 if (pHddCtx->isLoadUnloadInProgress)
9589 {
9590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9591 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9592 return 0;
9593 }
9594
9595 spin_lock(&pHddCtx->schedScan_lock);
9596 pHddCtx->isWiphySuspended = FALSE;
9597 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9598 {
9599 spin_unlock(&pHddCtx->schedScan_lock);
9600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9601 "%s: Return resume is not due to PNO indication", __func__);
9602 return 0;
9603 }
9604 // Reset flag to avoid updatating cfg80211 data old results again
9605 pHddCtx->isSchedScanUpdatePending = FALSE;
9606 spin_unlock(&pHddCtx->schedScan_lock);
9607
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309608
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309609 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9610
9611 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9612 {
9613 pAdapter = pAdapterNode->pAdapter;
9614 if ( (NULL != pAdapter) &&
9615 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9616 {
9617 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309618 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9620 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309621 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309622 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309623 {
9624 /* Acquire wakelock to handle the case where APP's tries to
9625 * suspend immediately after updating the scan results. Whis
9626 * results in app's is in suspended state and not able to
9627 * process the connect request to AP
9628 */
9629 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309630 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309631 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309632
9633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9634 "%s : cfg80211 scan result database updated", __func__);
9635
9636 return 0;
9637
9638 }
9639 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9640 pAdapterNode = pNext;
9641 }
9642
9643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9644 "%s: Failed to find Adapter", __func__);
9645 return 0;
9646}
9647
9648/*
9649 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9650 * this is called when cfg80211 driver suspends
9651 */
9652int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9653 struct cfg80211_wowlan *wow)
9654{
9655 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9656
9657 ENTER();
9658 if (NULL == pHddCtx)
9659 {
9660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9661 "%s: HddCtx validation failed", __func__);
9662 return 0;
9663 }
9664
9665 pHddCtx->isWiphySuspended = TRUE;
9666
9667 EXIT();
9668
9669 return 0;
9670}
9671
Jeff Johnson295189b2012-06-20 16:38:30 -07009672/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309673static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009674{
9675 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9676 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9677 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9678 .change_station = wlan_hdd_change_station,
9679#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9680 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9681 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9682 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009683#else
9684 .start_ap = wlan_hdd_cfg80211_start_ap,
9685 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9686 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009687#endif
9688 .change_bss = wlan_hdd_cfg80211_change_bss,
9689 .add_key = wlan_hdd_cfg80211_add_key,
9690 .get_key = wlan_hdd_cfg80211_get_key,
9691 .del_key = wlan_hdd_cfg80211_del_key,
9692 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009693#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009695#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 .scan = wlan_hdd_cfg80211_scan,
9697 .connect = wlan_hdd_cfg80211_connect,
9698 .disconnect = wlan_hdd_cfg80211_disconnect,
9699 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9700 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9701 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9702 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9703 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9705 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
9706 .mgmt_tx = wlan_hdd_action,
9707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9708 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9709 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9710 .set_txq_params = wlan_hdd_set_txq_params,
9711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 .get_station = wlan_hdd_cfg80211_get_station,
9713 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9714 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009715 .add_station = wlan_hdd_cfg80211_add_station,
9716#ifdef FEATURE_WLAN_LFR
9717 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9718 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9719 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9720#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009721#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9722 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9723#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009724#ifdef FEATURE_WLAN_TDLS
9725 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9726 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9727#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309728#ifdef WLAN_FEATURE_GTK_OFFLOAD
9729 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9730#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309731#ifdef FEATURE_WLAN_SCAN_PNO
9732 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9733 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9734#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309735 .resume = wlan_hdd_cfg80211_resume_wlan,
9736 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309737 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009738#ifdef WLAN_NL80211_TESTMODE
9739 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9740#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309741 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009742};
9743