blob: f83b494510c8042b1613af94c0e7a53600dc6d05 [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
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800785#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800786 if( pCfg->enableMCC )
787 {
788 /* Currently, supports up to two channels */
789 wlan_hdd_iface_combination.num_different_channels = 2;
790
791 if( !pCfg->allowMCCGODiffBI )
792 wlan_hdd_iface_combination.beacon_int_infra_match = true;
793
794 }
795 wiphy->iface_combinations = &wlan_hdd_iface_combination;
796 wiphy->n_iface_combinations = 1;
797#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800798
Jeff Johnson295189b2012-06-20 16:38:30 -0700799 /* Before registering we need to update the ht capabilitied based
800 * on ini values*/
801 if( !pCfg->ShortGI20MhzEnable )
802 {
803 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
804 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
805 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
806 }
807
808 if( !pCfg->ShortGI40MhzEnable )
809 {
810 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
811 }
812
813 if( !pCfg->nChannelBondingMode5GHz )
814 {
815 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
816 }
817
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530818 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530819 if (true == hdd_is_5g_supported(pHddCtx))
820 {
821 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
822 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530823
824 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
825 {
826
827 if (NULL == wiphy->bands[i])
828 {
829 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
830 __func__, i);
831 continue;
832 }
833
834 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
835 {
836 struct ieee80211_supported_band *band = wiphy->bands[i];
837
838 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
839 {
840 // Enable social channels for P2P
841 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
842 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
843 else
844 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
845 continue;
846 }
847 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
848 {
849 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
850 continue;
851 }
852 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 }
854 /*Initialise the supported cipher suite details*/
855 wiphy->cipher_suites = hdd_cipher_suites;
856 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
857
858 /*signal strength in mBm (100*dBm) */
859 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
860
861#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700862 wiphy->max_remain_on_channel_duration = 1000;
863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700864
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800865 wiphy->n_vendor_commands = 0;
866 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
867 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
868
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530869 EXIT();
870 return 0;
871}
872
873/* In this function we are registering wiphy. */
874int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
875{
876 ENTER();
877 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700878 if (0 > wiphy_register(wiphy))
879 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530880 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
882 return -EIO;
883 }
884
885 EXIT();
886 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530887}
Jeff Johnson295189b2012-06-20 16:38:30 -0700888
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530889/* In this function we are updating channel list when,
890 regulatory domain is FCC and country code is US.
891 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
892 As per FCC smart phone is not a indoor device.
893 GO should not opeate on indoor channels */
894void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
895{
896 int j;
897 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
898 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
899 //Default counrtycode from NV at the time of wiphy initialization.
900 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
901 &defaultCountryCode[0]))
902 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700903 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530904 }
905 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
906 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530907 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
908 {
909 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
910 return;
911 }
912 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
913 {
914 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
915 // Mark UNII -1 band channel as passive
916 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
917 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
918 }
919 }
920}
921
Jeff Johnson295189b2012-06-20 16:38:30 -0700922/* In this function we will do all post VOS start initialization.
923 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530924 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700925*/
926void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
927{
Jeff Johnson295189b2012-06-20 16:38:30 -0700928 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
929 /* Register for all P2P action, public action etc frames */
930 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
931
Jeff Johnsone7245742012-09-05 17:12:55 -0700932 ENTER();
933
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 /* Right now we are registering these frame when driver is getting
935 initialized. Once we will move to 2.6.37 kernel, in which we have
936 frame register ops, we will move this code as a part of that */
937 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530938 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700939 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
940
941 /* GAS Initial Response */
942 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
943 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 /* GAS Comeback Request */
946 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
947 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
948
949 /* GAS Comeback Response */
950 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
951 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
952
953 /* P2P Public Action */
954 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530955 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700956 P2P_PUBLIC_ACTION_FRAME_SIZE );
957
958 /* P2P Action */
959 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
960 (v_U8_t*)P2P_ACTION_FRAME,
961 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700962
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530963 /* WNM BSS Transition Request frame */
964 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
965 (v_U8_t*)WNM_BSS_ACTION_FRAME,
966 WNM_BSS_ACTION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700967}
968
969void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
970{
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
972 /* Register for all P2P action, public action etc frames */
973 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
974
Jeff Johnsone7245742012-09-05 17:12:55 -0700975 ENTER();
976
Jeff Johnson295189b2012-06-20 16:38:30 -0700977 /* Right now we are registering these frame when driver is getting
978 initialized. Once we will move to 2.6.37 kernel, in which we have
979 frame register ops, we will move this code as a part of that */
980 /* GAS Initial Request */
981
982 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
983 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
984
985 /* GAS Initial Response */
986 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
987 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530988
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 /* GAS Comeback Request */
990 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
991 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
992
993 /* GAS Comeback Response */
994 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
995 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
996
997 /* P2P Public Action */
998 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530999 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 P2P_PUBLIC_ACTION_FRAME_SIZE );
1001
1002 /* P2P Action */
1003 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1004 (v_U8_t*)P2P_ACTION_FRAME,
1005 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07001006
1007#ifdef WLAN_FEATURE_11W
1008 /* SA Query Response Action Frame */
1009 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1010 (v_U8_t*)SA_QUERY_FRAME_RSP,
1011 SA_QUERY_FRAME_RSP_SIZE );
1012#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001013}
1014
1015#ifdef FEATURE_WLAN_WAPI
1016void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1017 const u8 *mac_addr, u8 *key , int key_Len)
1018{
1019 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1020 tCsrRoamSetKey setKey;
1021 v_BOOL_t isConnected = TRUE;
1022 int status = 0;
1023 v_U32_t roamId= 0xFF;
1024 tANI_U8 *pKeyPtr = NULL;
1025 int n = 0;
1026
Arif Hussain6d2a3322013-11-17 19:50:10 -08001027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001028 __func__,pAdapter->device_mode);
1029
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301030 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 setKey.keyId = key_index; // Store Key ID
1032 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1033 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1034 setKey.paeRole = 0 ; // the PAE role
1035 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1036 {
1037 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1038 }
1039 else
1040 {
1041 isConnected = hdd_connIsConnected(pHddStaCtx);
1042 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1043 }
1044 setKey.keyLength = key_Len;
1045 pKeyPtr = setKey.Key;
1046 memcpy( pKeyPtr, key, key_Len);
1047
Arif Hussain6d2a3322013-11-17 19:50:10 -08001048 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001049 __func__, key_Len);
1050 for (n = 0 ; n < key_Len; n++)
1051 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1052 __func__,n,setKey.Key[n]);
1053
1054 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1055 if ( isConnected )
1056 {
1057 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1058 pAdapter->sessionId, &setKey, &roamId );
1059 }
1060 if ( status != 0 )
1061 {
1062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1063 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1064 __LINE__, status );
1065 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1066 }
1067}
1068#endif /* FEATURE_WLAN_WAPI*/
1069
1070#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301071int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 beacon_data_t **ppBeacon,
1073 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001074#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301075int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001076 beacon_data_t **ppBeacon,
1077 struct cfg80211_beacon_data *params,
1078 int dtim_period)
1079#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301080{
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 int size;
1082 beacon_data_t *beacon = NULL;
1083 beacon_data_t *old = NULL;
1084 int head_len,tail_len;
1085
Jeff Johnsone7245742012-09-05 17:12:55 -07001086 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301088 {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1090 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301092 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001093
1094 old = pAdapter->sessionCtx.ap.beacon;
1095
1096 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301097 {
1098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 FL("session(%d) old and new heads points to NULL"),
1100 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301102 }
1103
1104 if (params->tail && !params->tail_len)
1105 {
1106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1107 FL("tail_len is zero but tail is not NULL"));
1108 return -EINVAL;
1109 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001110
Jeff Johnson295189b2012-06-20 16:38:30 -07001111#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1112 /* Kernel 3.0 is not updating dtim_period for set beacon */
1113 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301114 {
1115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1116 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001119#endif
1120
1121 if(params->head)
1122 head_len = params->head_len;
1123 else
1124 head_len = old->head_len;
1125
1126 if(params->tail || !old)
1127 tail_len = params->tail_len;
1128 else
1129 tail_len = old->tail_len;
1130
1131 size = sizeof(beacon_data_t) + head_len + tail_len;
1132
1133 beacon = kzalloc(size, GFP_KERNEL);
1134
1135 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301136 {
1137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1138 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001141
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001142#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001143 if(params->dtim_period || !old )
1144 beacon->dtim_period = params->dtim_period;
1145 else
1146 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001147#else
1148 if(dtim_period || !old )
1149 beacon->dtim_period = dtim_period;
1150 else
1151 beacon->dtim_period = old->dtim_period;
1152#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301153
Jeff Johnson295189b2012-06-20 16:38:30 -07001154 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1155 beacon->tail = beacon->head + head_len;
1156 beacon->head_len = head_len;
1157 beacon->tail_len = tail_len;
1158
1159 if(params->head) {
1160 memcpy (beacon->head,params->head,beacon->head_len);
1161 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301162 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 if(old)
1164 memcpy (beacon->head,old->head,beacon->head_len);
1165 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301166
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 if(params->tail) {
1168 memcpy (beacon->tail,params->tail,beacon->tail_len);
1169 }
1170 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301171 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 memcpy (beacon->tail,old->tail,beacon->tail_len);
1173 }
1174
1175 *ppBeacon = beacon;
1176
1177 kfree(old);
1178
1179 return 0;
1180
1181}
Jeff Johnson295189b2012-06-20 16:38:30 -07001182
1183v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1184{
1185 int left = length;
1186 v_U8_t *ptr = pIes;
1187 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301188
Jeff Johnson295189b2012-06-20 16:38:30 -07001189 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301190 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001191 elem_id = ptr[0];
1192 elem_len = ptr[1];
1193 left -= 2;
1194 if(elem_len > left)
1195 {
1196 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001197 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 eid,elem_len,left);
1199 return NULL;
1200 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301201 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001202 {
1203 return ptr;
1204 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301205
Jeff Johnson295189b2012-06-20 16:38:30 -07001206 left -= elem_len;
1207 ptr += (elem_len + 2);
1208 }
1209 return NULL;
1210}
1211
Jeff Johnson295189b2012-06-20 16:38:30 -07001212/* Check if rate is 11g rate or not */
1213static int wlan_hdd_rate_is_11g(u8 rate)
1214{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001215 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001216 u8 i;
1217 for (i = 0; i < 8; i++)
1218 {
1219 if(rate == gRateArray[i])
1220 return TRUE;
1221 }
1222 return FALSE;
1223}
1224
1225/* Check for 11g rate and set proper 11g only mode */
1226static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1227 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1228{
1229 u8 i, num_rates = pIe[0];
1230
1231 pIe += 1;
1232 for ( i = 0; i < num_rates; i++)
1233 {
1234 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1235 {
1236 /* If rate set have 11g rate than change the mode to 11G */
1237 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1238 if (pIe[i] & BASIC_RATE_MASK)
1239 {
1240 /* If we have 11g rate as basic rate, it means mode
1241 is 11g only mode.
1242 */
1243 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1244 *pCheckRatesfor11g = FALSE;
1245 }
1246 }
1247 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1248 {
1249 *require_ht = TRUE;
1250 }
1251 }
1252 return;
1253}
1254
1255static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1256{
1257 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1258 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1259 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1260 u8 checkRatesfor11g = TRUE;
1261 u8 require_ht = FALSE;
1262 u8 *pIe=NULL;
1263
1264 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1265
1266 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1267 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1268 if (pIe != NULL)
1269 {
1270 pIe += 1;
1271 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1272 &pConfig->SapHw_mode);
1273 }
1274
1275 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1276 WLAN_EID_EXT_SUPP_RATES);
1277 if (pIe != NULL)
1278 {
1279
1280 pIe += 1;
1281 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1282 &pConfig->SapHw_mode);
1283 }
1284
1285 if( pConfig->channel > 14 )
1286 {
1287 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1288 }
1289
1290 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1291 WLAN_EID_HT_CAPABILITY);
1292
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301293 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 {
1295 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1296 if(require_ht)
1297 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1298 }
1299}
1300
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301301static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1302 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1303{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001304 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301305 v_U8_t *pIe = NULL;
1306 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1307
1308 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1309 pBeacon->tail, pBeacon->tail_len);
1310
1311 if (pIe)
1312 {
1313 ielen = pIe[1] + 2;
1314 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1315 {
1316 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1317 }
1318 else
1319 {
1320 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1321 return -EINVAL;
1322 }
1323 *total_ielen += ielen;
1324 }
1325 return 0;
1326}
1327
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001328static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1329 v_U8_t *genie, v_U8_t *total_ielen)
1330{
1331 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1332 int left = pBeacon->tail_len;
1333 v_U8_t *ptr = pBeacon->tail;
1334 v_U8_t elem_id, elem_len;
1335 v_U16_t ielen = 0;
1336
1337 if ( NULL == ptr || 0 == left )
1338 return;
1339
1340 while (left >= 2)
1341 {
1342 elem_id = ptr[0];
1343 elem_len = ptr[1];
1344 left -= 2;
1345 if (elem_len > left)
1346 {
1347 hddLog( VOS_TRACE_LEVEL_ERROR,
1348 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1349 elem_id, elem_len, left);
1350 return;
1351 }
1352 if (IE_EID_VENDOR == elem_id)
1353 {
1354 /* skipping the VSIE's which we don't want to include or
1355 * it will be included by existing code
1356 */
1357 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1358#ifdef WLAN_FEATURE_WFD
1359 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1360#endif
1361 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1362 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1363 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1364 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1365 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1366 {
1367 ielen = ptr[1] + 2;
1368 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1369 {
1370 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1371 *total_ielen += ielen;
1372 }
1373 else
1374 {
1375 hddLog( VOS_TRACE_LEVEL_ERROR,
1376 "IE Length is too big "
1377 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1378 elem_id, elem_len, *total_ielen);
1379 }
1380 }
1381 }
1382
1383 left -= elem_len;
1384 ptr += (elem_len + 2);
1385 }
1386 return;
1387}
1388
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001389#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001390static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1391 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001392#else
1393static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1394 struct cfg80211_beacon_data *params)
1395#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001396{
1397 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301398 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001400 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001401
1402 genie = vos_mem_malloc(MAX_GENIE_LEN);
1403
1404 if(genie == NULL) {
1405
1406 return -ENOMEM;
1407 }
1408
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301409 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1410 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001411 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301412 hddLog(LOGE,
1413 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301414 ret = -EINVAL;
1415 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001416 }
1417
1418#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301419 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1420 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1421 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301422 hddLog(LOGE,
1423 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301424 ret = -EINVAL;
1425 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 }
1427#endif
1428
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301429 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1430 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301432 hddLog(LOGE,
1433 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301434 ret = -EINVAL;
1435 goto done;
1436 }
1437
1438 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1439 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001440 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001442
1443 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1444 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1445 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1446 {
1447 hddLog(LOGE,
1448 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001449 ret = -EINVAL;
1450 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001451 }
1452
1453 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1454 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1455 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1456 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1457 ==eHAL_STATUS_FAILURE)
1458 {
1459 hddLog(LOGE,
1460 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001461 ret = -EINVAL;
1462 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 }
1464
1465 // Added for ProResp IE
1466 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1467 {
1468 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1469 u8 probe_rsp_ie_len[3] = {0};
1470 u8 counter = 0;
1471 /* Check Probe Resp Length if it is greater then 255 then Store
1472 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1473 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1474 Store More then 255 bytes into One Variable.
1475 */
1476 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1477 {
1478 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1479 {
1480 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1481 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1482 }
1483 else
1484 {
1485 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1486 rem_probe_resp_ie_len = 0;
1487 }
1488 }
1489
1490 rem_probe_resp_ie_len = 0;
1491
1492 if (probe_rsp_ie_len[0] > 0)
1493 {
1494 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1495 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1496 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1497 probe_rsp_ie_len[0], NULL,
1498 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1499 {
1500 hddLog(LOGE,
1501 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001502 ret = -EINVAL;
1503 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001504 }
1505 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1506 }
1507
1508 if (probe_rsp_ie_len[1] > 0)
1509 {
1510 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1511 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1512 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1513 probe_rsp_ie_len[1], NULL,
1514 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1515 {
1516 hddLog(LOGE,
1517 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001518 ret = -EINVAL;
1519 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001520 }
1521 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1522 }
1523
1524 if (probe_rsp_ie_len[2] > 0)
1525 {
1526 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1527 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1528 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1529 probe_rsp_ie_len[2], NULL,
1530 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1531 {
1532 hddLog(LOGE,
1533 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001534 ret = -EINVAL;
1535 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001536 }
1537 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1538 }
1539
1540 if (probe_rsp_ie_len[1] == 0 )
1541 {
1542 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1543 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1544 eANI_BOOLEAN_FALSE) )
1545 {
1546 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001547 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 }
1549 }
1550
1551 if (probe_rsp_ie_len[2] == 0 )
1552 {
1553 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1554 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1555 eANI_BOOLEAN_FALSE) )
1556 {
1557 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001558 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 }
1560 }
1561
1562 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1563 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1564 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1565 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1566 == eHAL_STATUS_FAILURE)
1567 {
1568 hddLog(LOGE,
1569 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001570 ret = -EINVAL;
1571 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 }
1573 }
1574 else
1575 {
1576 // Reset WNI_CFG_PROBE_RSP Flags
1577 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1578
1579 hddLog(VOS_TRACE_LEVEL_INFO,
1580 "%s: No Probe Response IE received in set beacon",
1581 __func__);
1582 }
1583
1584 // Added for AssocResp IE
1585 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1586 {
1587 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1588 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1589 params->assocresp_ies_len, NULL,
1590 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1591 {
1592 hddLog(LOGE,
1593 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001594 ret = -EINVAL;
1595 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 }
1597
1598 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1599 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1600 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1601 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1602 == eHAL_STATUS_FAILURE)
1603 {
1604 hddLog(LOGE,
1605 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001606 ret = -EINVAL;
1607 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 }
1609 }
1610 else
1611 {
1612 hddLog(VOS_TRACE_LEVEL_INFO,
1613 "%s: No Assoc Response IE received in set beacon",
1614 __func__);
1615
1616 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1617 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1618 eANI_BOOLEAN_FALSE) )
1619 {
1620 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001621 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001622 }
1623 }
1624
Jeff Johnsone7245742012-09-05 17:12:55 -07001625done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001626 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301627 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001628}
Jeff Johnson295189b2012-06-20 16:38:30 -07001629
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301630/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 * FUNCTION: wlan_hdd_validate_operation_channel
1632 * called by wlan_hdd_cfg80211_start_bss() and
1633 * wlan_hdd_cfg80211_set_channel()
1634 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301635 * channel list.
1636 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001637VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001638{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301639
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 v_U32_t num_ch = 0;
1641 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1642 u32 indx = 0;
1643 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301644 v_U8_t fValidChannel = FALSE, count = 0;
1645 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301646
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1648
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301649 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301651 /* Validate the channel */
1652 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301654 if ( channel == rfChannels[count].channelNum )
1655 {
1656 fValidChannel = TRUE;
1657 break;
1658 }
1659 }
1660 if (fValidChannel != TRUE)
1661 {
1662 hddLog(VOS_TRACE_LEVEL_ERROR,
1663 "%s: Invalid Channel [%d]", __func__, channel);
1664 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 }
1666 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301667 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301669 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1670 valid_ch, &num_ch))
1671 {
1672 hddLog(VOS_TRACE_LEVEL_ERROR,
1673 "%s: failed to get valid channel list", __func__);
1674 return VOS_STATUS_E_FAILURE;
1675 }
1676 for (indx = 0; indx < num_ch; indx++)
1677 {
1678 if (channel == valid_ch[indx])
1679 {
1680 break;
1681 }
1682 }
1683
1684 if (indx >= num_ch)
1685 {
1686 hddLog(VOS_TRACE_LEVEL_ERROR,
1687 "%s: Invalid Channel [%d]", __func__, channel);
1688 return VOS_STATUS_E_FAILURE;
1689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 }
1691 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301692
Jeff Johnson295189b2012-06-20 16:38:30 -07001693}
1694
Viral Modi3a32cc52013-02-08 11:14:52 -08001695/**
1696 * FUNCTION: wlan_hdd_cfg80211_set_channel
1697 * This function is used to set the channel number
1698 */
1699static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1700 struct ieee80211_channel *chan,
1701 enum nl80211_channel_type channel_type
1702 )
1703{
1704 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001705 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001706 hdd_adapter_t *pAdapter = NULL;
1707 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301708 hdd_context_t *pHddCtx;
1709 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001710
1711 ENTER();
1712
1713 if( NULL == dev )
1714 {
1715 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001716 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001717 return -ENODEV;
1718 }
1719 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1720
1721 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001722 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001723 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301724
1725 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1726 status = wlan_hdd_validate_context(pHddCtx);
1727
1728 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001729 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1731 "%s: HDD context is not valid", __func__);
1732 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001733 }
1734
1735 /*
1736 * Do freq to chan conversion
1737 * TODO: for 11a
1738 */
1739
1740 channel = ieee80211_frequency_to_channel(freq);
1741
1742 /* Check freq range */
1743 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1744 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001747 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001748 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1749 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1750 return -EINVAL;
1751 }
1752
1753 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1754
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301755 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1756 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001757 {
1758 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001761 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001762 return -EINVAL;
1763 }
1764 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1765 "%s: set channel to [%d] for device mode =%d",
1766 __func__, channel,pAdapter->device_mode);
1767 }
1768 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001769 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001770 )
1771 {
1772 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1773 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1774 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1775
1776 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1777 {
1778 /* Link is up then return cant set channel*/
1779 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001780 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001781 return -EINVAL;
1782 }
1783
1784 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1785 pHddStaCtx->conn_info.operationChannel = channel;
1786 pRoamProfile->ChannelInfo.ChannelList =
1787 &pHddStaCtx->conn_info.operationChannel;
1788 }
1789 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001790 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001791 )
1792 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301793 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1794 {
1795 if(VOS_STATUS_SUCCESS !=
1796 wlan_hdd_validate_operation_channel(pAdapter,channel))
1797 {
1798 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001799 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301800 return -EINVAL;
1801 }
1802 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1803 }
1804 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001805 {
1806 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1807
1808 /* If auto channel selection is configured as enable/ 1 then ignore
1809 channel set by supplicant
1810 */
1811 if ( cfg_param->apAutoChannelSelection )
1812 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301813 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1814 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001815 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1816 "%s: set channel to auto channel (0) for device mode =%d",
1817 __func__, pAdapter->device_mode);
1818 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301819 else
1820 {
1821 if(VOS_STATUS_SUCCESS !=
1822 wlan_hdd_validate_operation_channel(pAdapter,channel))
1823 {
1824 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001825 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301826 return -EINVAL;
1827 }
1828 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1829 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001830 }
1831 }
1832 else
1833 {
1834 hddLog(VOS_TRACE_LEVEL_FATAL,
1835 "%s: Invalid device mode failed to set valid channel", __func__);
1836 return -EINVAL;
1837 }
1838 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301839 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001840}
1841
Jeff Johnson295189b2012-06-20 16:38:30 -07001842#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1843static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1844 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001845#else
1846static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1847 struct cfg80211_beacon_data *params,
1848 const u8 *ssid, size_t ssid_len,
1849 enum nl80211_hidden_ssid hidden_ssid)
1850#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001851{
1852 tsap_Config_t *pConfig;
1853 beacon_data_t *pBeacon = NULL;
1854 struct ieee80211_mgmt *pMgmt_frame;
1855 v_U8_t *pIe=NULL;
1856 v_U16_t capab_info;
1857 eCsrAuthType RSNAuthType;
1858 eCsrEncryptionType RSNEncryptType;
1859 eCsrEncryptionType mcRSNEncryptType;
1860 int status = VOS_STATUS_SUCCESS;
1861 tpWLAN_SAPEventCB pSapEventCallback;
1862 hdd_hostapd_state_t *pHostapdState;
1863 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1864 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301865 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001866 struct qc_mac_acl_entry *acl_entry = NULL;
1867 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001868 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001869 v_BOOL_t MFPCapable;
1870 v_BOOL_t MFPRequired;
Jeff Johnson295189b2012-06-20 16:38:30 -07001871
1872 ENTER();
1873
1874 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1875
1876 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1877
1878 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1879
1880 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1881
1882 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1883
1884 //channel is already set in the set_channel Call back
1885 //pConfig->channel = pCommitConfig->channel;
1886
1887 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301888 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001889 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1890
1891 pConfig->dtim_period = pBeacon->dtim_period;
1892
Arif Hussain6d2a3322013-11-17 19:50:10 -08001893 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 pConfig->dtim_period);
1895
1896
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001897 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001898 {
1899 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001900 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301901 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1902 {
1903 tANI_BOOLEAN restartNeeded;
1904 pConfig->ieee80211d = 1;
1905 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1906 sme_setRegInfo(hHal, pConfig->countryCode);
1907 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1908 }
1909 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001910 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001911 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001912 pConfig->ieee80211d = 1;
1913 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1914 sme_setRegInfo(hHal, pConfig->countryCode);
1915 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001916 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001917 else
1918 {
1919 pConfig->ieee80211d = 0;
1920 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301921 /*
1922 * If auto channel is configured i.e. channel is 0,
1923 * so skip channel validation.
1924 */
1925 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1926 {
1927 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001930 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301931 return -EINVAL;
1932 }
1933 }
1934 else
1935 {
1936 if(1 != pHddCtx->is_dynamic_channel_range_set)
1937 {
1938 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1939 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1940 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1941 }
1942 pHddCtx->is_dynamic_channel_range_set = 0;
1943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001944 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001945 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 {
1947 pConfig->ieee80211d = 0;
1948 }
1949 pConfig->authType = eSAP_AUTO_SWITCH;
1950
1951 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301952
1953 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001954 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1955
1956 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1957
1958 /*Set wps station to configured*/
1959 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1960
1961 if(pIe)
1962 {
1963 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1964 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001965 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 return -EINVAL;
1967 }
1968 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1969 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001970 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 /* Check 15 bit of WPS IE as it contain information for wps state
1972 * WPS state
1973 */
1974 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1975 {
1976 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1977 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1978 {
1979 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1980 }
1981 }
1982 }
1983 else
1984 {
1985 pConfig->wps_state = SAP_WPS_DISABLED;
1986 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301987 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001988
1989 pConfig->RSNWPAReqIELength = 0;
1990 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301991 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001992 WLAN_EID_RSN);
1993 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301994 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1996 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1997 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301998 /* The actual processing may eventually be more extensive than
1999 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 * by the app.
2001 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302002 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2004 &RSNEncryptType,
2005 &mcRSNEncryptType,
2006 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002007 &MFPCapable,
2008 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 pConfig->pRSNWPAReqIE[1]+2,
2010 pConfig->pRSNWPAReqIE );
2011
2012 if( VOS_STATUS_SUCCESS == status )
2013 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302014 /* Now copy over all the security attributes you have
2015 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002016 * */
2017 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2018 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2019 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2020 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302021 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002022 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2024 }
2025 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302026
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2028 pBeacon->tail, pBeacon->tail_len);
2029
2030 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2031 {
2032 if (pConfig->pRSNWPAReqIE)
2033 {
2034 /*Mixed mode WPA/WPA2*/
2035 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2036 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2037 }
2038 else
2039 {
2040 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2041 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2042 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302043 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2045 &RSNEncryptType,
2046 &mcRSNEncryptType,
2047 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002048 &MFPCapable,
2049 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002050 pConfig->pRSNWPAReqIE[1]+2,
2051 pConfig->pRSNWPAReqIE );
2052
2053 if( VOS_STATUS_SUCCESS == status )
2054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302055 /* Now copy over all the security attributes you have
2056 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 * */
2058 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2059 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2060 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2061 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302062 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002063 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2065 }
2066 }
2067 }
2068
Jeff Johnson4416a782013-03-25 14:17:50 -07002069 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2070 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2071 return -EINVAL;
2072 }
2073
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002076#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 if (params->ssid != NULL)
2078 {
2079 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2080 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2081 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2082 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2083 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002084#else
2085 if (ssid != NULL)
2086 {
2087 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2088 pConfig->SSIDinfo.ssid.length = ssid_len;
2089 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2090 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2091 }
2092#endif
2093
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302094 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302096
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 /* default value */
2098 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2099 pConfig->num_accept_mac = 0;
2100 pConfig->num_deny_mac = 0;
2101
2102 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2103 pBeacon->tail, pBeacon->tail_len);
2104
2105 /* pIe for black list is following form:
2106 type : 1 byte
2107 length : 1 byte
2108 OUI : 4 bytes
2109 acl type : 1 byte
2110 no of mac addr in black list: 1 byte
2111 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112 */
2113 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 {
2115 pConfig->SapMacaddr_acl = pIe[6];
2116 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002117 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302119 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2120 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2122 for (i = 0; i < pConfig->num_deny_mac; i++)
2123 {
2124 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2125 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 }
2128 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2129 pBeacon->tail, pBeacon->tail_len);
2130
2131 /* pIe for white list is following form:
2132 type : 1 byte
2133 length : 1 byte
2134 OUI : 4 bytes
2135 acl type : 1 byte
2136 no of mac addr in white list: 1 byte
2137 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302138 */
2139 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 {
2141 pConfig->SapMacaddr_acl = pIe[6];
2142 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002143 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002144 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302145 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2146 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2148 for (i = 0; i < pConfig->num_accept_mac; i++)
2149 {
2150 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2151 acl_entry++;
2152 }
2153 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302154
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2156
Jeff Johnsone7245742012-09-05 17:12:55 -07002157#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002158 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302159 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2160 * 11ac in .ini and 11ac is supported by both host and firmware.
2161 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2162 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002163 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2164 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302165 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002166 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
Kiet Lam0f320422013-11-21 19:29:17 +05302167 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) &&
2168 (sme_IsFeatureSupportedByDriver(DOT11AC)) && (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002169 {
2170 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002171
2172 /* Disable VHT support in 2.4 GHz band */
2173 if (pConfig->channel <= 14 &&
2174 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2175 {
2176 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2177 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002178 }
2179#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302180
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002181 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2182 {
2183 sme_SelectCBMode(hHal,
2184 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2185 pConfig->channel);
2186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 // ht_capab is not what the name conveys,this is used for protection bitmap
2188 pConfig->ht_capab =
2189 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2190
2191 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2192 {
2193 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2194 return -EINVAL;
2195 }
2196
2197 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302198 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2200 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302201 pConfig->obssProtEnabled =
2202 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002203
Chet Lanctot8cecea22014-02-11 19:09:36 -08002204#ifdef WLAN_FEATURE_11W
2205 pConfig->mfpCapable = MFPCapable;
2206 pConfig->mfpRequired = MFPRequired;
2207 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2208 pConfig->mfpCapable, pConfig->mfpRequired);
2209#endif
2210
Arif Hussain6d2a3322013-11-17 19:50:10 -08002211 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002213 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2214 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2215 (int)pConfig->channel);
2216 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2217 pConfig->SapHw_mode, pConfig->privacy,
2218 pConfig->authType);
2219 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2220 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2221 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2222 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002223
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302224 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 {
2226 //Bss already started. just return.
2227 //TODO Probably it should update some beacon params.
2228 hddLog( LOGE, "Bss Already started...Ignore the request");
2229 EXIT();
2230 return 0;
2231 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302232
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 pConfig->persona = pHostapdAdapter->device_mode;
2234
2235 pSapEventCallback = hdd_hostapd_SAPEventCB;
2236 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2237 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2238 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002239 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002240 return -EINVAL;
2241 }
2242
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302243 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2245
2246 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302247
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302249 {
2250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002251 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002252 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 VOS_ASSERT(0);
2254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302255
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 //Succesfully started Bss update the state bit.
2257 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2258
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002259#ifdef WLAN_FEATURE_P2P_DEBUG
2260 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2261 {
2262 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2263 {
2264 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2265 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002266 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002267 }
2268 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2269 {
2270 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2271 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002272 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002273 }
2274 }
2275#endif
2276
Jeff Johnson295189b2012-06-20 16:38:30 -07002277 pHostapdState->bCommit = TRUE;
2278 EXIT();
2279
2280 return 0;
2281}
2282
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302284static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2285 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002286 struct beacon_parameters *params)
2287{
2288 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302289 hdd_context_t *pHddCtx;
2290 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002291
2292 ENTER();
2293
Arif Hussain6d2a3322013-11-17 19:50:10 -08002294 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002295
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2297 status = wlan_hdd_validate_context(pHddCtx);
2298
2299 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002300 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2302 "%s: HDD context is not valid", __func__);
2303 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002304 }
2305
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302306 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 )
2309 {
2310 beacon_data_t *old,*new;
2311
2312 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302313
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302315 {
2316 hddLog(VOS_TRACE_LEVEL_WARN,
2317 FL("already beacon info added to session(%d)"),
2318 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002319 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002321
2322 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2323
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302324 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002325 {
2326 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002327 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002328 return -EINVAL;
2329 }
2330
2331 pAdapter->sessionCtx.ap.beacon = new;
2332
2333 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2334 }
2335
2336 EXIT();
2337 return status;
2338}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302339
2340static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002341 struct net_device *dev,
2342 struct beacon_parameters *params)
2343{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302344 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302345 hdd_context_t *pHddCtx;
2346 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002347
2348 ENTER();
2349
Arif Hussain6d2a3322013-11-17 19:50:10 -08002350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 __func__,pAdapter->device_mode);
2352
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2354 status = wlan_hdd_validate_context(pHddCtx);
2355
2356 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002357 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2359 "%s: HDD context is not valid", __func__);
2360 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002361 }
2362
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302363 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302365 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 {
2367 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302368
Jeff Johnson295189b2012-06-20 16:38:30 -07002369 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302370
Jeff Johnson295189b2012-06-20 16:38:30 -07002371 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302372 {
2373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2374 FL("session(%d) old and new heads points to NULL"),
2375 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002376 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002378
2379 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2380
2381 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302382 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002383 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 return -EINVAL;
2385 }
2386
2387 pAdapter->sessionCtx.ap.beacon = new;
2388
2389 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2390 }
2391
2392 EXIT();
2393 return status;
2394}
2395
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2397
2398#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002399static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2400 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002401#else
2402static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2403 struct net_device *dev)
2404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002405{
2406 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002407 hdd_context_t *pHddCtx = NULL;
2408 hdd_scaninfo_t *pScanInfo = NULL;
2409 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302410 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002411
2412 ENTER();
2413
2414 if (NULL == pAdapter)
2415 {
2416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002417 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002418 return -ENODEV;
2419 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002420
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2422 status = wlan_hdd_validate_context(pHddCtx);
2423
2424 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002425 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2427 "%s: HDD context is not valid", __func__);
2428 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002429 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002430
2431 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2432 if (NULL == staAdapter)
2433 {
2434 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2435 if (NULL == staAdapter)
2436 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2438 "%s: HDD adapter context for STA/P2P-CLI is Null",
2439 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002440 }
2441 }
2442
2443 pScanInfo = &pHddCtx->scan_info;
2444
Arif Hussain6d2a3322013-11-17 19:50:10 -08002445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002446 __func__,pAdapter->device_mode);
2447
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002448 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002449 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302450 long ret;
2451
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002452 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302453 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2454 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302455 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002456 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002457 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302458 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002459 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302461 FL("Timeout occurred while waiting for abortscan %ld"),
2462 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002463
2464 if (pHddCtx->isLogpInProgress)
2465 {
2466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302468
2469 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002470 return -EAGAIN;
2471 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002472 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002473 }
2474 }
2475
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302476 hdd_hostapd_stop(dev);
2477
Jeff Johnson295189b2012-06-20 16:38:30 -07002478 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002479 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002480 )
2481 {
2482 beacon_data_t *old;
2483
2484 old = pAdapter->sessionCtx.ap.beacon;
2485
2486 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302487 {
2488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2489 FL("session(%d) beacon data points to NULL"),
2490 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002491 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302492 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002493
Jeff Johnson295189b2012-06-20 16:38:30 -07002494 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002495
2496 mutex_lock(&pHddCtx->sap_lock);
2497 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2498 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002499 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002500 {
2501 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2502
2503 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2504
2505 if (!VOS_IS_STATUS_SUCCESS(status))
2506 {
2507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002508 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 VOS_ASSERT(0);
2510 }
2511 }
2512 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2513 }
2514 mutex_unlock(&pHddCtx->sap_lock);
2515
2516 if(status != VOS_STATUS_SUCCESS)
2517 {
2518 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002519 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002520 return -EINVAL;
2521 }
2522
Jeff Johnson4416a782013-03-25 14:17:50 -07002523 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002524 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2525 ==eHAL_STATUS_FAILURE)
2526 {
2527 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002528 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 }
2530
Jeff Johnson4416a782013-03-25 14:17:50 -07002531 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2533 eANI_BOOLEAN_FALSE) )
2534 {
2535 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002536 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002537 }
2538
2539 // Reset WNI_CFG_PROBE_RSP Flags
2540 wlan_hdd_reset_prob_rspies(pAdapter);
2541
2542 pAdapter->sessionCtx.ap.beacon = NULL;
2543 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002544#ifdef WLAN_FEATURE_P2P_DEBUG
2545 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2546 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2547 {
2548 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2549 "GO got removed");
2550 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2551 }
2552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 }
2554 EXIT();
2555 return status;
2556}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002557
2558#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2559
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302560static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2561 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002562 struct cfg80211_ap_settings *params)
2563{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302564 hdd_adapter_t *pAdapter;
2565 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302566 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002567
2568 ENTER();
2569
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302570 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002571 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302573 "%s: Device is Null", __func__);
2574 return -ENODEV;
2575 }
2576
2577 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2578 if (NULL == pAdapter)
2579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302581 "%s: HDD adapter is Null", __func__);
2582 return -ENODEV;
2583 }
2584
2585 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2586 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302588 "%s: HDD adapter magic is invalid", __func__);
2589 return -ENODEV;
2590 }
2591
2592 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302593 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302594
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302595 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302596 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2598 "%s: HDD context is not valid", __func__);
2599 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302600 }
2601
2602 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2603 __func__, pAdapter->device_mode);
2604
2605 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002606 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002607 )
2608 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302609 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002610
2611 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302612
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002613 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302614 {
2615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2616 FL("already beacon info added to session(%d)"),
2617 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002618 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302619 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002620
2621 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2622
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302623 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002624 {
2625 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302626 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002627 return -EINVAL;
2628 }
2629 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002631 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2632#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2633 params->channel, params->channel_type);
2634#else
2635 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2636#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002637#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002638 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2639 params->ssid_len, params->hidden_ssid);
2640 }
2641
2642 EXIT();
2643 return status;
2644}
2645
2646
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302647static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002648 struct net_device *dev,
2649 struct cfg80211_beacon_data *params)
2650{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302651 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302652 hdd_context_t *pHddCtx;
2653 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002654
2655 ENTER();
2656
Arif Hussain6d2a3322013-11-17 19:50:10 -08002657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002658 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302659
2660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2661 status = wlan_hdd_validate_context(pHddCtx);
2662
2663 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002664 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2666 "%s: HDD context is not valid", __func__);
2667 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002668 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002669
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302670 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002671 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302672 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002673 {
2674 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302675
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002676 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302677
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002678 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302679 {
2680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2681 FL("session(%d) beacon data points to NULL"),
2682 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002683 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302684 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002685
2686 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2687
2688 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302689 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002690 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002691 return -EINVAL;
2692 }
2693
2694 pAdapter->sessionCtx.ap.beacon = new;
2695
2696 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2697 }
2698
2699 EXIT();
2700 return status;
2701}
2702
2703#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2704
Jeff Johnson295189b2012-06-20 16:38:30 -07002705
2706static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2707 struct net_device *dev,
2708 struct bss_parameters *params)
2709{
2710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2711
2712 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302713
Arif Hussain6d2a3322013-11-17 19:50:10 -08002714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002715 __func__,pAdapter->device_mode);
2716
2717 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002718 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302719 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002720 {
2721 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2722 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302723 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002724 {
2725 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002727 }
2728
2729 EXIT();
2730 return 0;
2731}
2732
Kiet Lam10841362013-11-01 11:36:50 +05302733/* FUNCTION: wlan_hdd_change_country_code_cd
2734* to wait for contry code completion
2735*/
2736void* wlan_hdd_change_country_code_cb(void *pAdapter)
2737{
2738 hdd_adapter_t *call_back_pAdapter = pAdapter;
2739 complete(&call_back_pAdapter->change_country_code);
2740 return NULL;
2741}
2742
Jeff Johnson295189b2012-06-20 16:38:30 -07002743/*
2744 * FUNCTION: wlan_hdd_cfg80211_change_iface
2745 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2746 */
2747int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2748 struct net_device *ndev,
2749 enum nl80211_iftype type,
2750 u32 *flags,
2751 struct vif_params *params
2752 )
2753{
2754 struct wireless_dev *wdev;
2755 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002756 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002757 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002758 tCsrRoamProfile *pRoamProfile = NULL;
2759 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302760 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002761 eMib_dot11DesiredBssType connectedBssType;
2762 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302763 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002764
2765 ENTER();
2766
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002767 if (!pAdapter)
2768 {
2769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Adapter context is null", __func__);
2771 return VOS_STATUS_E_FAILURE;
2772 }
2773
2774 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2775 if (!pHddCtx)
2776 {
2777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2778 "%s: HDD context is null", __func__);
2779 return VOS_STATUS_E_FAILURE;
2780 }
2781
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302782 status = wlan_hdd_validate_context(pHddCtx);
2783
2784 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002785 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2787 "%s: HDD context is not valid", __func__);
2788 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002789 }
2790
2791 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2792 __func__, pAdapter->device_mode);
2793
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302794 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002795 wdev = ndev->ieee80211_ptr;
2796
2797#ifdef WLAN_BTAMP_FEATURE
2798 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2799 (NL80211_IFTYPE_ADHOC == type)||
2800 (NL80211_IFTYPE_AP == type)||
2801 (NL80211_IFTYPE_P2P_GO == type))
2802 {
2803 pHddCtx->isAmpAllowed = VOS_FALSE;
2804 // stop AMP traffic
2805 status = WLANBAP_StopAmp();
2806 if(VOS_STATUS_SUCCESS != status )
2807 {
2808 pHddCtx->isAmpAllowed = VOS_TRUE;
2809 hddLog(VOS_TRACE_LEVEL_FATAL,
2810 "%s: Failed to stop AMP", __func__);
2811 return -EINVAL;
2812 }
2813 }
2814#endif //WLAN_BTAMP_FEATURE
2815 /* Reset the current device mode bit mask*/
2816 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2817
2818 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002819 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002820 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002821 )
2822 {
2823 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002824 if (!pWextState)
2825 {
2826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2827 "%s: pWextState is null", __func__);
2828 return VOS_STATUS_E_FAILURE;
2829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002830 pRoamProfile = &pWextState->roamProfile;
2831 LastBSSType = pRoamProfile->BSSType;
2832
2833 switch (type)
2834 {
2835 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002837 hddLog(VOS_TRACE_LEVEL_INFO,
2838 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2839 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002840#ifdef WLAN_FEATURE_11AC
2841 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2842 {
2843 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2844 }
2845#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302846 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002847 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002848 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002849 //Check for sub-string p2p to confirm its a p2p interface
2850 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302851 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002852 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2853 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2854 }
2855 else
2856 {
2857 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002858 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002859 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302860#ifdef FEATURE_WLAN_TDLS
2861 /* The open adapter for the p2p shall skip initializations in
2862 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2863 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2864 * tdls_init when the change_iface sets the device mode to
2865 * WLAN_HDD_P2P_CLIENT.
2866 */
2867
2868 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2869 {
2870 if (0 != wlan_hdd_tdls_init (pAdapter))
2871 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302872 hddLog(VOS_TRACE_LEVEL_ERROR,
2873 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302874 return -EINVAL;
2875 }
2876 }
2877#endif
2878
Jeff Johnson295189b2012-06-20 16:38:30 -07002879 break;
2880 case NL80211_IFTYPE_ADHOC:
2881 hddLog(VOS_TRACE_LEVEL_INFO,
2882 "%s: setting interface Type to ADHOC", __func__);
2883 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2884 pRoamProfile->phyMode =
2885 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002886 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 wdev->iftype = type;
2888 break;
2889
2890 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002891 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002892 {
2893 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2894 "%s: setting interface Type to %s", __func__,
2895 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2896
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002897 //Cancel any remain on channel for GO mode
2898 if (NL80211_IFTYPE_P2P_GO == type)
2899 {
2900 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2901 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002902 if (NL80211_IFTYPE_AP == type)
2903 {
2904 /* As Loading WLAN Driver one interface being created for p2p device
2905 * address. This will take one HW STA and the max number of clients
2906 * that can connect to softAP will be reduced by one. so while changing
2907 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2908 * interface as it is not required in SoftAP mode.
2909 */
2910
2911 // Get P2P Adapter
2912 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2913
2914 if (pP2pAdapter)
2915 {
2916 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2917 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2918 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2919 }
2920 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302921#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002922
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302923 /* A Mutex Lock is introduced while changing the mode to
2924 * protect the concurrent access for the Adapters by TDLS
2925 * module.
2926 */
2927 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2928 {
2929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2930 "%s: unable to lock list", __func__);
2931 return -EINVAL;
2932 }
2933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002934 //De-init the adapter.
2935 hdd_stop_adapter( pHddCtx, pAdapter );
2936 hdd_deinit_adapter( pHddCtx, pAdapter );
2937 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2939 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302940#ifdef FEATURE_WLAN_TDLS
2941 mutex_unlock(&pHddCtx->tdls_lock);
2942#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002943
2944 //Disable BMPS and IMPS if enabled
2945 //before starting Go
2946 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302948 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002949 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2950 {
2951 //Fail to Exit BMPS
2952 VOS_ASSERT(0);
2953 }
2954 }
2955
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002956 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2957 (pConfig->apRandomBssidEnabled))
2958 {
2959 /* To meet Android requirements create a randomized
2960 MAC address of the form 02:1A:11:Fx:xx:xx */
2961 get_random_bytes(&ndev->dev_addr[3], 3);
2962 ndev->dev_addr[0] = 0x02;
2963 ndev->dev_addr[1] = 0x1A;
2964 ndev->dev_addr[2] = 0x11;
2965 ndev->dev_addr[3] |= 0xF0;
2966 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2967 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002968 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2969 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002970 }
2971
Jeff Johnson295189b2012-06-20 16:38:30 -07002972 hdd_set_ap_ops( pAdapter->dev );
2973
Kiet Lam10841362013-11-01 11:36:50 +05302974 /* This is for only SAP mode where users can
2975 * control country through ini.
2976 * P2P GO follows station country code
2977 * acquired during the STA scanning. */
2978 if((NL80211_IFTYPE_AP == type) &&
2979 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
2980 {
2981 int status = 0;
2982 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
2983 "%s: setting country code from INI ", __func__);
2984 init_completion(&pAdapter->change_country_code);
2985 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2986 (void *)(tSmeChangeCountryCallback)
2987 wlan_hdd_change_country_code_cb,
2988 pConfig->apCntryCode, pAdapter,
2989 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05302990 eSIR_FALSE,
2991 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05302992 if (eHAL_STATUS_SUCCESS == status)
2993 {
2994 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302995 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05302996 &pAdapter->change_country_code,
2997 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302998 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05302999 {
3000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303001 FL("SME Timed out while setting country code %ld"),
3002 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003003
3004 if (pHddCtx->isLogpInProgress)
3005 {
3006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3007 "%s: LOGP in Progress. Ignore!!!", __func__);
3008 return -EAGAIN;
3009 }
Kiet Lam10841362013-11-01 11:36:50 +05303010 }
3011 }
3012 else
3013 {
3014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003015 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303016 return -EINVAL;
3017 }
3018 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003019 status = hdd_init_ap_mode(pAdapter);
3020 if(status != VOS_STATUS_SUCCESS)
3021 {
3022 hddLog(VOS_TRACE_LEVEL_FATAL,
3023 "%s: Error initializing the ap mode", __func__);
3024 return -EINVAL;
3025 }
3026 hdd_set_conparam(1);
3027
Jeff Johnson295189b2012-06-20 16:38:30 -07003028 /*interface type changed update in wiphy structure*/
3029 if(wdev)
3030 {
3031 wdev->iftype = type;
3032 pHddCtx->change_iface = type;
3033 }
3034 else
3035 {
3036 hddLog(VOS_TRACE_LEVEL_ERROR,
3037 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3038 return -EINVAL;
3039 }
3040 goto done;
3041 }
3042
3043 default:
3044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3045 __func__);
3046 return -EOPNOTSUPP;
3047 }
3048 }
3049 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003050 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003051 )
3052 {
3053 switch(type)
3054 {
3055 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003056 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003057 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303058#ifdef FEATURE_WLAN_TDLS
3059
3060 /* A Mutex Lock is introduced while changing the mode to
3061 * protect the concurrent access for the Adapters by TDLS
3062 * module.
3063 */
3064 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
3065 {
3066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3067 "%s: unable to lock list", __func__);
3068 return -EINVAL;
3069 }
3070#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003071 hdd_stop_adapter( pHddCtx, pAdapter );
3072 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003073 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003074 //Check for sub-string p2p to confirm its a p2p interface
3075 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003076 {
3077 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3078 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3079 }
3080 else
3081 {
3082 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003083 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003085 hdd_set_conparam(0);
3086 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003087 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3088 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303089#ifdef FEATURE_WLAN_TDLS
3090 mutex_unlock(&pHddCtx->tdls_lock);
3091#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303092 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003093 if( VOS_STATUS_SUCCESS != status )
3094 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003095 /* In case of JB, for P2P-GO, only change interface will be called,
3096 * This is the right place to enable back bmps_imps()
3097 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303098 if (pHddCtx->hdd_wlan_suspended)
3099 {
3100 hdd_set_pwrparams(pHddCtx);
3101 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003102 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 goto done;
3104 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003105 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003106 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003107 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3108 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 goto done;
3110 default:
3111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3112 __func__);
3113 return -EOPNOTSUPP;
3114
3115 }
3116
3117 }
3118 else
3119 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303120 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3121 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003122 return -EOPNOTSUPP;
3123 }
3124
3125
3126 if(pRoamProfile)
3127 {
3128 if ( LastBSSType != pRoamProfile->BSSType )
3129 {
3130 /*interface type changed update in wiphy structure*/
3131 wdev->iftype = type;
3132
3133 /*the BSS mode changed, We need to issue disconnect
3134 if connected or in IBSS disconnect state*/
3135 if ( hdd_connGetConnectedBssType(
3136 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3137 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3138 {
3139 /*need to issue a disconnect to CSR.*/
3140 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3141 if( eHAL_STATUS_SUCCESS ==
3142 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3143 pAdapter->sessionId,
3144 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3145 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303146 ret = wait_for_completion_interruptible_timeout(
3147 &pAdapter->disconnect_comp_var,
3148 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3149 if (ret <= 0)
3150 {
3151 hddLog(VOS_TRACE_LEVEL_ERROR,
3152 FL("wait on disconnect_comp_var failed %ld"), ret);
3153 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003154 }
3155 }
3156 }
3157 }
3158
3159done:
3160 /*set bitmask based on updated value*/
3161 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003162
3163 /* Only STA mode support TM now
3164 * all other mode, TM feature should be disabled */
3165 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3166 (~VOS_STA & pHddCtx->concurrency_mode) )
3167 {
3168 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3169 }
3170
Jeff Johnson295189b2012-06-20 16:38:30 -07003171#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303172 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003173 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3174 {
3175 //we are ok to do AMP
3176 pHddCtx->isAmpAllowed = VOS_TRUE;
3177 }
3178#endif //WLAN_BTAMP_FEATURE
3179 EXIT();
3180 return 0;
3181}
3182
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003183#ifdef FEATURE_WLAN_TDLS
3184static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3185 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3186{
3187 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3188 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3189 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003190 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303191 long ret;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003192
3193 ENTER();
3194
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303195 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003196 {
3197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3198 "Invalid arguments");
3199 return -EINVAL;
3200 }
Hoonki Lee27511902013-03-14 18:19:06 -07003201
3202 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3203 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3204 {
3205 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3206 "%s: TDLS mode is disabled OR not enabled in FW."
3207 MAC_ADDRESS_STR " Request declined.",
3208 __func__, MAC_ADDR_ARRAY(mac));
3209 return -ENOTSUPP;
3210 }
3211
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003212 if (pHddCtx->isLogpInProgress)
3213 {
3214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3215 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003216 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003217 return -EBUSY;
3218 }
3219
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303220 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003221
3222 if ( NULL == pTdlsPeer ) {
3223 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3224 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3225 __func__, MAC_ADDR_ARRAY(mac), update);
3226 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003227 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003228
3229 /* in add station, we accept existing valid staId if there is */
3230 if ((0 == update) &&
3231 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3232 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003233 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003234 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003235 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003236 " link_status %d. staId %d. add station ignored.",
3237 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3238 return 0;
3239 }
3240 /* in change station, we accept only when staId is valid */
3241 if ((1 == update) &&
3242 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3243 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3244 {
3245 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3246 "%s: " MAC_ADDRESS_STR
3247 " link status %d. staId %d. change station %s.",
3248 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3249 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3250 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003251 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003252
3253 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303254 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003255 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3257 "%s: " MAC_ADDRESS_STR
3258 " TDLS setup is ongoing. Request declined.",
3259 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003260 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003261 }
3262
3263 /* first to check if we reached to maximum supported TDLS peer.
3264 TODO: for now, return -EPERM looks working fine,
3265 but need to check if any other errno fit into this category.*/
3266 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
3267 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3269 "%s: " MAC_ADDRESS_STR
3270 " TDLS Max peer already connected. Request declined.",
3271 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003272 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003273 }
3274 else
3275 {
3276 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303277 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003278 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003279 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3282 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003283 return -EPERM;
3284 }
3285 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003286 if (0 == update)
3287 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003288
Jeff Johnsond75fe012013-04-06 10:53:06 -07003289 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303290 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003291 {
3292 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3293 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003294 if(StaParams->htcap_present)
3295 {
3296 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3297 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3298 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3299 "ht_capa->extended_capabilities: %0x",
3300 StaParams->HTCap.extendedHtCapInfo);
3301 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003302 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3303 "params->capability: %0x",StaParams->capability);
3304 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003305 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003306 if(StaParams->vhtcap_present)
3307 {
3308 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3309 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3310 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3311 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3312 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003313 {
3314 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003316 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3317 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3318 "[%d]: %x ", i, StaParams->supported_rates[i]);
3319 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003320 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303321 else if ((1 == update) && (NULL == StaParams))
3322 {
3323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3324 "%s : update is true, but staParams is NULL. Error!", __func__);
3325 return -EPERM;
3326 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003327
3328 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3329
3330 if (!update)
3331 {
3332 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3333 pAdapter->sessionId, mac);
3334 }
3335 else
3336 {
3337 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3338 pAdapter->sessionId, mac, StaParams);
3339 }
3340
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303341 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003342 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3343
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303344 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003345 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303347 "%s: timeout waiting for tdls add station indication %ld",
3348 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003349 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003350 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303351
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003352 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3353 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003355 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003356 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003357 }
3358
3359 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003360
3361error:
3362 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3363 return -EPERM;
3364
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003365}
3366#endif
3367
Jeff Johnson295189b2012-06-20 16:38:30 -07003368static int wlan_hdd_change_station(struct wiphy *wiphy,
3369 struct net_device *dev,
3370 u8 *mac,
3371 struct station_parameters *params)
3372{
3373 VOS_STATUS status = VOS_STATUS_SUCCESS;
3374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303375 hdd_context_t *pHddCtx;
3376 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003377 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003378#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003379 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003380 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303381 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003382#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003383 ENTER();
3384
Gopichand Nakkala29149562013-05-10 21:43:41 +05303385 if ((NULL == pAdapter))
3386 {
3387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3388 "invalid adapter ");
3389 return -EINVAL;
3390 }
3391
3392 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3393 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3394
3395 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3396 {
3397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3398 "invalid HDD state or HDD station context");
3399 return -EINVAL;
3400 }
3401
3402 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003403 {
3404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "%s:LOGP in Progress. Ignore!!!", __func__);
3406 return -EAGAIN;
3407 }
3408
Jeff Johnson295189b2012-06-20 16:38:30 -07003409 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3410
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003411 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3412 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003413 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003414 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003415 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303416 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 WLANTL_STA_AUTHENTICATED);
3418
Gopichand Nakkala29149562013-05-10 21:43:41 +05303419 if (status != VOS_STATUS_SUCCESS)
3420 {
3421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3422 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3423 return -EINVAL;
3424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003425 }
3426 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003427 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3428 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303429#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003430 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3431 StaParams.capability = params->capability;
3432 StaParams.uapsd_queues = params->uapsd_queues;
3433 StaParams.max_sp = params->max_sp;
3434
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303435 /* Convert (first channel , number of channels) tuple to
3436 * the total list of channels. This goes with the assumption
3437 * that if the first channel is < 14, then the next channels
3438 * are an incremental of 1 else an incremental of 4 till the number
3439 * of channels.
3440 */
3441 if (0 != params->supported_channels_len) {
3442 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3443 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3444 {
3445 int wifi_chan_index;
3446 StaParams.supported_channels[j] = params->supported_channels[i];
3447 wifi_chan_index =
3448 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3449 no_of_channels = params->supported_channels[i+1];
3450 for(k=1; k <= no_of_channels; k++)
3451 {
3452 StaParams.supported_channels[j+1] =
3453 StaParams.supported_channels[j] + wifi_chan_index;
3454 j+=1;
3455 }
3456 }
3457 StaParams.supported_channels_len = j;
3458 }
3459 vos_mem_copy(StaParams.supported_oper_classes,
3460 params->supported_oper_classes,
3461 params->supported_oper_classes_len);
3462 StaParams.supported_oper_classes_len =
3463 params->supported_oper_classes_len;
3464
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003465 if (0 != params->ext_capab_len)
3466 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3467 sizeof(StaParams.extn_capability));
3468
3469 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003470 {
3471 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003472 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003473 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003474
3475 StaParams.supported_rates_len = params->supported_rates_len;
3476
3477 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3478 * The supported_rates array , for all the structures propogating till Add Sta
3479 * to the firmware has to be modified , if the supplicant (ieee80211) is
3480 * modified to send more rates.
3481 */
3482
3483 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3484 */
3485 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3486 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3487
3488 if (0 != StaParams.supported_rates_len) {
3489 int i = 0;
3490 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3491 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003493 "Supported Rates with Length %d", StaParams.supported_rates_len);
3494 for (i=0; i < StaParams.supported_rates_len; i++)
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 "[%d]: %0x", i, StaParams.supported_rates[i]);
3497 }
3498
3499 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003500 {
3501 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003502 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003503 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003504
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003505 if (0 != params->ext_capab_len ) {
3506 /*Define A Macro : TODO Sunil*/
3507 if ((1<<4) & StaParams.extn_capability[3]) {
3508 isBufSta = 1;
3509 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303510 /* TDLS Channel Switching Support */
3511 if ((1<<6) & StaParams.extn_capability[3]) {
3512 isOffChannelSupported = 1;
3513 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003514 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303515 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3516 &StaParams, isBufSta,
3517 isOffChannelSupported);
3518
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303519 if (VOS_STATUS_SUCCESS != status) {
3520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3521 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3522 return -EINVAL;
3523 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003524 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3525
3526 if (VOS_STATUS_SUCCESS != status) {
3527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3528 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3529 return -EINVAL;
3530 }
3531 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003532#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303533 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003534 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003535 return status;
3536}
3537
3538/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003539 * FUNCTION: wlan_hdd_cfg80211_add_key
3540 * This function is used to initialize the key information
3541 */
3542#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003543static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003544 struct net_device *ndev,
3545 u8 key_index, bool pairwise,
3546 const u8 *mac_addr,
3547 struct key_params *params
3548 )
3549#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003550static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003551 struct net_device *ndev,
3552 u8 key_index, const u8 *mac_addr,
3553 struct key_params *params
3554 )
3555#endif
3556{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003557 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003558 tCsrRoamSetKey setKey;
3559 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303560 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003561 v_U32_t roamId= 0xFF;
3562 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003563 hdd_hostapd_state_t *pHostapdState;
3564 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003565 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303566 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003567
3568 ENTER();
3569
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303570 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3571 status = wlan_hdd_validate_context(pHddCtx);
3572
3573 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003574 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3576 "%s: HDD context is not valid", __func__);
3577 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003578 }
3579
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003580 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3581 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003582
3583 if (CSR_MAX_NUM_KEY <= key_index)
3584 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 key_index);
3587
3588 return -EINVAL;
3589 }
3590
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003591 if (CSR_MAX_KEY_LEN < params->key_len)
3592 {
3593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3594 params->key_len);
3595
3596 return -EINVAL;
3597 }
3598
3599 hddLog(VOS_TRACE_LEVEL_INFO,
3600 "%s: called with key index = %d & key length %d",
3601 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003602
3603 /*extract key idx, key len and key*/
3604 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3605 setKey.keyId = key_index;
3606 setKey.keyLength = params->key_len;
3607 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3608
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003609 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 {
3611 case WLAN_CIPHER_SUITE_WEP40:
3612 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3613 break;
3614
3615 case WLAN_CIPHER_SUITE_WEP104:
3616 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3617 break;
3618
3619 case WLAN_CIPHER_SUITE_TKIP:
3620 {
3621 u8 *pKey = &setKey.Key[0];
3622 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3623
3624 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3625
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003626 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003627
3628 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003629 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 |--------------|----------|----------|
3631 <---16bytes---><--8bytes--><--8bytes-->
3632
3633 */
3634 /*Sme expects the 32 bytes key to be in the below order
3635
3636 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003637 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003638 |--------------|----------|----------|
3639 <---16bytes---><--8bytes--><--8bytes-->
3640 */
3641 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003642 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003643
3644 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003645 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003646
3647 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003648 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003649
3650
3651 break;
3652 }
3653
3654 case WLAN_CIPHER_SUITE_CCMP:
3655 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3656 break;
3657
3658#ifdef FEATURE_WLAN_WAPI
3659 case WLAN_CIPHER_SUITE_SMS4:
3660 {
3661 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3662 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3663 params->key, params->key_len);
3664 return 0;
3665 }
3666#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003667
Jeff Johnson295189b2012-06-20 16:38:30 -07003668#ifdef FEATURE_WLAN_CCX
3669 case WLAN_CIPHER_SUITE_KRK:
3670 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3671 break;
3672#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003673
3674#ifdef WLAN_FEATURE_11W
3675 case WLAN_CIPHER_SUITE_AES_CMAC:
3676 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003677 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003678#endif
3679
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 __func__, params->cipher);
3683 return -EOPNOTSUPP;
3684 }
3685
3686 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3687 __func__, setKey.encType);
3688
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003689 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003690#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3691 (!pairwise)
3692#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003693 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003694#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003695 )
3696 {
3697 /* set group key*/
3698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3699 "%s- %d: setting Broadcast key",
3700 __func__, __LINE__);
3701 setKey.keyDirection = eSIR_RX_ONLY;
3702 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3703 }
3704 else
3705 {
3706 /* set pairwise key*/
3707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3708 "%s- %d: setting pairwise key",
3709 __func__, __LINE__);
3710 setKey.keyDirection = eSIR_TX_RX;
3711 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3712 }
3713 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3714 {
3715 setKey.keyDirection = eSIR_TX_RX;
3716 /*Set the group key*/
3717 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3718 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003719
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003720 if ( 0 != status )
3721 {
3722 hddLog(VOS_TRACE_LEVEL_ERROR,
3723 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3724 return -EINVAL;
3725 }
3726 /*Save the keys here and call sme_RoamSetKey for setting
3727 the PTK after peer joins the IBSS network*/
3728 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3729 &setKey, sizeof(tCsrRoamSetKey));
3730 return status;
3731 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303732 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3733 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3734 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003736 if( pHostapdState->bssState == BSS_START )
3737 {
c_hpothu7c55da62014-01-23 18:34:02 +05303738 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3739 vos_status = wlan_hdd_check_ula_done(pAdapter);
3740
3741 if ( vos_status != VOS_STATUS_SUCCESS )
3742 {
3743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3744 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3745 __LINE__, vos_status );
3746
3747 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3748
3749 return -EINVAL;
3750 }
3751
Jeff Johnson295189b2012-06-20 16:38:30 -07003752 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3753
3754 if ( status != eHAL_STATUS_SUCCESS )
3755 {
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3757 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3758 __LINE__, status );
3759 }
3760 }
3761
3762 /* Saving WEP keys */
3763 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3764 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3765 {
3766 //Save the wep key in ap context. Issue setkey after the BSS is started.
3767 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3768 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3769 }
3770 else
3771 {
3772 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003773 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003774 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3775 }
3776 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003777 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3778 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003779 {
3780 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3781 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3782
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3784 if (!pairwise)
3785#else
3786 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3787#endif
3788 {
3789 /* set group key*/
3790 if (pHddStaCtx->roam_info.deferKeyComplete)
3791 {
3792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3793 "%s- %d: Perform Set key Complete",
3794 __func__, __LINE__);
3795 hdd_PerformRoamSetKeyComplete(pAdapter);
3796 }
3797 }
3798
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3800
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003801 pWextState->roamProfile.Keys.defaultIndex = key_index;
3802
3803
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003804 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003805 params->key, params->key_len);
3806
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303807
Jeff Johnson295189b2012-06-20 16:38:30 -07003808 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3809
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303810 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003811 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303812 __func__, setKey.peerMac[0], setKey.peerMac[1],
3813 setKey.peerMac[2], setKey.peerMac[3],
3814 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003815 setKey.keyDirection);
3816
3817 vos_status = wlan_hdd_check_ula_done(pAdapter);
3818
3819 if ( vos_status != VOS_STATUS_SUCCESS )
3820 {
3821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3822 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3823 __LINE__, vos_status );
3824
3825 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3826
3827 return -EINVAL;
3828
3829 }
3830
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003831#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303832 /* The supplicant may attempt to set the PTK once pre-authentication
3833 is done. Save the key in the UMAC and include it in the ADD BSS
3834 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003835 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303836 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003837 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303838 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3839 "%s: Update PreAuth Key success", __func__);
3840 return 0;
3841 }
3842 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3843 {
3844 hddLog(VOS_TRACE_LEVEL_ERROR,
3845 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303846 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003847 }
3848#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003849
3850 /* issue set key request to SME*/
3851 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3852 pAdapter->sessionId, &setKey, &roamId );
3853
3854 if ( 0 != status )
3855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303856 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003857 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3858 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3859 return -EINVAL;
3860 }
3861
3862
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303863 /* in case of IBSS as there was no information available about WEP keys during
3864 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003865 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303866 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3867 !( ( IW_AUTH_KEY_MGMT_802_1X
3868 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003869 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3870 )
3871 &&
3872 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3873 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3874 )
3875 )
3876 {
3877 setKey.keyDirection = eSIR_RX_ONLY;
3878 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3879
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303880 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003881 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303882 __func__, setKey.peerMac[0], setKey.peerMac[1],
3883 setKey.peerMac[2], setKey.peerMac[3],
3884 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 setKey.keyDirection);
3886
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303887 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 pAdapter->sessionId, &setKey, &roamId );
3889
3890 if ( 0 != status )
3891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303892 hddLog(VOS_TRACE_LEVEL_ERROR,
3893 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003894 __func__, status);
3895 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3896 return -EINVAL;
3897 }
3898 }
3899 }
3900
3901 return 0;
3902}
3903
3904/*
3905 * FUNCTION: wlan_hdd_cfg80211_get_key
3906 * This function is used to get the key information
3907 */
3908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303909static int wlan_hdd_cfg80211_get_key(
3910 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003911 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303912 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003913 const u8 *mac_addr, void *cookie,
3914 void (*callback)(void *cookie, struct key_params*)
3915 )
3916#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303917static int wlan_hdd_cfg80211_get_key(
3918 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003919 struct net_device *ndev,
3920 u8 key_index, const u8 *mac_addr, void *cookie,
3921 void (*callback)(void *cookie, struct key_params*)
3922 )
3923#endif
3924{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303925 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003926 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3927 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3928 struct key_params params;
3929
3930 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303931
Arif Hussain6d2a3322013-11-17 19:50:10 -08003932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303934
Jeff Johnson295189b2012-06-20 16:38:30 -07003935 memset(&params, 0, sizeof(params));
3936
3937 if (CSR_MAX_NUM_KEY <= key_index)
3938 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003940 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003942
3943 switch(pRoamProfile->EncryptionType.encryptionType[0])
3944 {
3945 case eCSR_ENCRYPT_TYPE_NONE:
3946 params.cipher = IW_AUTH_CIPHER_NONE;
3947 break;
3948
3949 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3950 case eCSR_ENCRYPT_TYPE_WEP40:
3951 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3952 break;
3953
3954 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3955 case eCSR_ENCRYPT_TYPE_WEP104:
3956 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3957 break;
3958
3959 case eCSR_ENCRYPT_TYPE_TKIP:
3960 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3961 break;
3962
3963 case eCSR_ENCRYPT_TYPE_AES:
3964 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3965 break;
3966
3967 default:
3968 params.cipher = IW_AUTH_CIPHER_NONE;
3969 break;
3970 }
3971
3972 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3973 params.seq_len = 0;
3974 params.seq = NULL;
3975 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3976 callback(cookie, &params);
3977 return 0;
3978}
3979
3980/*
3981 * FUNCTION: wlan_hdd_cfg80211_del_key
3982 * This function is used to delete the key information
3983 */
3984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303985static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303987 u8 key_index,
3988 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003989 const u8 *mac_addr
3990 )
3991#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303992static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 struct net_device *ndev,
3994 u8 key_index,
3995 const u8 *mac_addr
3996 )
3997#endif
3998{
3999 int status = 0;
4000
4001 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304002 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004003 //it is observed that this is invalidating peer
4004 //key index whenever re-key is done. This is affecting data link.
4005 //It should be ok to ignore del_key.
4006#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4008 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004009 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4010 tCsrRoamSetKey setKey;
4011 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304012
Jeff Johnson295189b2012-06-20 16:38:30 -07004013 ENTER();
4014
4015 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4016 __func__,pAdapter->device_mode);
4017
4018 if (CSR_MAX_NUM_KEY <= key_index)
4019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004021 key_index);
4022
4023 return -EINVAL;
4024 }
4025
4026 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4027 setKey.keyId = key_index;
4028
4029 if (mac_addr)
4030 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4031 else
4032 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4033
4034 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4035
4036 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004037 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304038 )
4039 {
4040
4041 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4043 if( pHostapdState->bssState == BSS_START)
4044 {
4045 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304046
Jeff Johnson295189b2012-06-20 16:38:30 -07004047 if ( status != eHAL_STATUS_SUCCESS )
4048 {
4049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4050 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4051 __LINE__, status );
4052 }
4053 }
4054 }
4055 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004057 )
4058 {
4059 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4060
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304061 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4062
4063 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004064 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304065 __func__, setKey.peerMac[0], setKey.peerMac[1],
4066 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004067 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304068 if(pAdapter->sessionCtx.station.conn_info.connState ==
4069 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004072 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304073
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 if ( 0 != status )
4075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304076 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004077 "%s: sme_RoamSetKey failure, returned %d",
4078 __func__, status);
4079 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4080 return -EINVAL;
4081 }
4082 }
4083 }
4084#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004085 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004086 return status;
4087}
4088
4089/*
4090 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4091 * This function is used to set the default tx key index
4092 */
4093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4094static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4095 struct net_device *ndev,
4096 u8 key_index,
4097 bool unicast, bool multicast)
4098#else
4099static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4100 struct net_device *ndev,
4101 u8 key_index)
4102#endif
4103{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304104 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304105 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304106 hdd_wext_state_t *pWextState;
4107 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304108 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004109
4110 ENTER();
4111
Gopichand Nakkala29149562013-05-10 21:43:41 +05304112 if ((NULL == pAdapter))
4113 {
4114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4115 "invalid adapter");
4116 return -EINVAL;
4117 }
4118
4119 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4120 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4121
4122 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4123 {
4124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4125 "invalid Wext state or HDD context");
4126 return -EINVAL;
4127 }
4128
Arif Hussain6d2a3322013-11-17 19:50:10 -08004129 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004130 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304131
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 if (CSR_MAX_NUM_KEY <= key_index)
4133 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004135 key_index);
4136
4137 return -EINVAL;
4138 }
4139
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304140 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4141 status = wlan_hdd_validate_context(pHddCtx);
4142
4143 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004144 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4146 "%s: HDD context is not valid", __func__);
4147 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004148 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149
Jeff Johnson295189b2012-06-20 16:38:30 -07004150 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004151 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304152 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304154 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004155 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304156 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004157 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304159 {
4160 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304162
Jeff Johnson295189b2012-06-20 16:38:30 -07004163 tCsrRoamSetKey setKey;
4164 v_U32_t roamId= 0xFF;
4165 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304166
4167 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004168 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169
Jeff Johnson295189b2012-06-20 16:38:30 -07004170 Keys->defaultIndex = (u8)key_index;
4171 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4172 setKey.keyId = key_index;
4173 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304174
4175 vos_mem_copy(&setKey.Key[0],
4176 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304178
Gopichand Nakkala29149562013-05-10 21:43:41 +05304179 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304180
4181 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 &pHddStaCtx->conn_info.bssId[0],
4183 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304184
Gopichand Nakkala29149562013-05-10 21:43:41 +05304185 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4186 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4187 eCSR_ENCRYPT_TYPE_WEP104)
4188 {
4189 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4190 even though ap is configured for WEP-40 encryption. In this canse the key length
4191 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4192 type(104) and switching encryption type to 40*/
4193 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4194 eCSR_ENCRYPT_TYPE_WEP40;
4195 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4196 eCSR_ENCRYPT_TYPE_WEP40;
4197 }
4198
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304199 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004200 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304201
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304203 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004204 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304205
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 if ( 0 != status )
4207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304208 hddLog(VOS_TRACE_LEVEL_ERROR,
4209 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 status);
4211 return -EINVAL;
4212 }
4213 }
4214 }
4215
4216 /* In SoftAp mode setting key direction for default mode */
4217 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4218 {
4219 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4220 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4221 (eCSR_ENCRYPT_TYPE_AES !=
4222 pWextState->roamProfile.EncryptionType.encryptionType[0])
4223 )
4224 {
4225 /* Saving key direction for default key index to TX default */
4226 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4227 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4228 }
4229 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304230
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 return status;
4232}
4233
Jeff Johnson295189b2012-06-20 16:38:30 -07004234/*
4235 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4236 * This function is used to inform the BSS details to nl80211 interface.
4237 */
4238static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4239 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4240{
4241 struct net_device *dev = pAdapter->dev;
4242 struct wireless_dev *wdev = dev->ieee80211_ptr;
4243 struct wiphy *wiphy = wdev->wiphy;
4244 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4245 int chan_no;
4246 int ie_length;
4247 const char *ie;
4248 unsigned int freq;
4249 struct ieee80211_channel *chan;
4250 int rssi = 0;
4251 struct cfg80211_bss *bss = NULL;
4252
4253 ENTER();
4254
4255 if( NULL == pBssDesc )
4256 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004257 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 return bss;
4259 }
4260
4261 chan_no = pBssDesc->channelId;
4262 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4263 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4264
4265 if( NULL == ie )
4266 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004267 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004268 return bss;
4269 }
4270
4271#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4272 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4273 {
4274 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4275 }
4276 else
4277 {
4278 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4279 }
4280#else
4281 freq = ieee80211_channel_to_frequency(chan_no);
4282#endif
4283
4284 chan = __ieee80211_get_channel(wiphy, freq);
4285
4286 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4287 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4288 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4289 if (bss == NULL)
4290 {
4291 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4292
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304293 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4294 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004295 pBssDesc->capabilityInfo,
4296 pBssDesc->beaconInterval, ie, ie_length,
4297 rssi, GFP_KERNEL ));
4298}
4299 else
4300 {
4301 return bss;
4302 }
4303}
4304
4305
4306
4307/*
4308 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4309 * This function is used to inform the BSS details to nl80211 interface.
4310 */
4311struct cfg80211_bss*
4312wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4313 tSirBssDescription *bss_desc
4314 )
4315{
4316 /*
4317 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4318 already exists in bss data base of cfg80211 for that particular BSS ID.
4319 Using cfg80211_inform_bss_frame to update the bss entry instead of
4320 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4321 now there is no possibility to get the mgmt(probe response) frame from PE,
4322 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4323 cfg80211_inform_bss_frame.
4324 */
4325 struct net_device *dev = pAdapter->dev;
4326 struct wireless_dev *wdev = dev->ieee80211_ptr;
4327 struct wiphy *wiphy = wdev->wiphy;
4328 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004329#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4330 qcom_ie_age *qie_age = NULL;
4331 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4332#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004333 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004334#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004335 const char *ie =
4336 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4337 unsigned int freq;
4338 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304339 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004340 struct cfg80211_bss *bss_status = NULL;
4341 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4342 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004343 hdd_context_t *pHddCtx;
4344 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004345#ifdef WLAN_OPEN_SOURCE
4346 struct timespec ts;
4347#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004348
Wilson Yangf80a0542013-10-07 13:02:37 -07004349 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4350 status = wlan_hdd_validate_context(pHddCtx);
4351
4352 /*bss_update is not allowed during wlan driver loading or unloading*/
4353 if (pHddCtx->isLoadUnloadInProgress)
4354 {
4355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4356 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4357 return NULL;
4358 }
4359
4360
4361 if (0 != status)
4362 {
4363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4364 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004365 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004366 }
4367
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304368 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004369 if (!mgmt)
4370 {
4371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4372 "%s: memory allocation failed ", __func__);
4373 return NULL;
4374 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004375
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004377
4378#ifdef WLAN_OPEN_SOURCE
4379 /* Android does not want the timestamp from the frame.
4380 Instead it wants a monotonic increasing value */
4381 get_monotonic_boottime(&ts);
4382 mgmt->u.probe_resp.timestamp =
4383 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4384#else
4385 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004386 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4387 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004388
4389#endif
4390
Jeff Johnson295189b2012-06-20 16:38:30 -07004391 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4392 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004393
4394#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4395 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4396 /* Assuming this is the last IE, copy at the end */
4397 ie_length -=sizeof(qcom_ie_age);
4398 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4399 qie_age->element_id = QCOM_VENDOR_IE_ID;
4400 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4401 qie_age->oui_1 = QCOM_OUI1;
4402 qie_age->oui_2 = QCOM_OUI2;
4403 qie_age->oui_3 = QCOM_OUI3;
4404 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4405 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4406#endif
4407
Jeff Johnson295189b2012-06-20 16:38:30 -07004408 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304409 if (bss_desc->fProbeRsp)
4410 {
4411 mgmt->frame_control |=
4412 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4413 }
4414 else
4415 {
4416 mgmt->frame_control |=
4417 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004419
4420#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304421 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4423 {
4424 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4425 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304426 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004427 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4428
4429 {
4430 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4431 }
4432 else
4433 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4435 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004436 kfree(mgmt);
4437 return NULL;
4438 }
4439#else
4440 freq = ieee80211_channel_to_frequency(chan_no);
4441#endif
4442 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004443 /*when the band is changed on the fly using the GUI, three things are done
4444 * 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)
4445 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4446 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4447 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4448 * and discards the channels correponding to previous band and calls back with zero bss results.
4449 * 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
4450 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4451 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4452 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4453 * So drop the bss and continue to next bss.
4454 */
4455 if(chan == NULL)
4456 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304457 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004458 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004459 return NULL;
4460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304462 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 * */
4464 if (( eConnectionState_Associated ==
4465 pAdapter->sessionCtx.station.conn_info.connState ) &&
4466 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4467 pAdapter->sessionCtx.station.conn_info.bssId,
4468 WNI_CFG_BSSID_LEN)))
4469 {
4470 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4471 rssi = (pAdapter->rssi * 100);
4472 }
4473 else
4474 {
4475 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4476 }
4477
Nirav Shah20ac06f2013-12-12 18:14:06 +05304478 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4479 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4480 chan->center_freq, (int)(rssi/100));
4481
Jeff Johnson295189b2012-06-20 16:38:30 -07004482 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4483 frame_len, rssi, GFP_KERNEL);
4484 kfree(mgmt);
4485 return bss_status;
4486}
4487
4488/*
4489 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4490 * This function is used to update the BSS data base of CFG8011
4491 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304492struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004493 tCsrRoamInfo *pRoamInfo
4494 )
4495{
4496 tCsrRoamConnectedProfile roamProfile;
4497 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4498 struct cfg80211_bss *bss = NULL;
4499
4500 ENTER();
4501
4502 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4503 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4504
4505 if (NULL != roamProfile.pBssDesc)
4506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304507 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004508 &roamProfile);
4509
4510 if (NULL == bss)
4511 {
4512 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4513 __func__);
4514 }
4515
4516 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4517 }
4518 else
4519 {
4520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4521 __func__);
4522 }
4523 return bss;
4524}
4525
4526/*
4527 * FUNCTION: wlan_hdd_cfg80211_update_bss
4528 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304529static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4530 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004531 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304532{
Jeff Johnson295189b2012-06-20 16:38:30 -07004533 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4534 tCsrScanResultInfo *pScanResult;
4535 eHalStatus status = 0;
4536 tScanResultHandle pResult;
4537 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004538 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004539
4540 ENTER();
4541
Wilson Yangf80a0542013-10-07 13:02:37 -07004542 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4543
4544 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004545 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4547 "%s:LOGP in Progress. Ignore!!!",__func__);
4548 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 }
4550
Wilson Yangf80a0542013-10-07 13:02:37 -07004551
4552 /*bss_update is not allowed during wlan driver loading or unloading*/
4553 if (pHddCtx->isLoadUnloadInProgress)
4554 {
4555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4556 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4557 return VOS_STATUS_E_PERM;
4558 }
4559
4560
Jeff Johnson295189b2012-06-20 16:38:30 -07004561 /*
4562 * start getting scan results and populate cgf80211 BSS database
4563 */
4564 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4565
4566 /* no scan results */
4567 if (NULL == pResult)
4568 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304569 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4570 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004571 return status;
4572 }
4573
4574 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4575
4576 while (pScanResult)
4577 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304578 /*
4579 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4580 * entry already exists in bss data base of cfg80211 for that
4581 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4582 * bss entry instead of cfg80211_inform_bss, But this call expects
4583 * mgmt packet as input. As of now there is no possibility to get
4584 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004585 * ieee80211_mgmt(probe response) and passing to c
4586 * fg80211_inform_bss_frame.
4587 * */
4588
4589 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4590 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304591
Jeff Johnson295189b2012-06-20 16:38:30 -07004592
4593 if (NULL == bss_status)
4594 {
4595 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004596 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 }
4598 else
4599 {
Yue Maf49ba872013-08-19 12:04:25 -07004600 cfg80211_put_bss(
4601#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4602 wiphy,
4603#endif
4604 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004605 }
4606
4607 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4608 }
4609
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304610 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004611
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304612 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004613}
4614
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004615void
4616hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4617{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304618 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004619 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004620} /****** end hddPrintMacAddr() ******/
4621
4622void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004623hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004624{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304625 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004626 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004627 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4628 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4629 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004630} /****** end hddPrintPmkId() ******/
4631
4632//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4633//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4634
4635//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4636//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4637
4638#define dump_bssid(bssid) \
4639 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004640 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4641 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004642 }
4643
4644#define dump_pmkid(pMac, pmkid) \
4645 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004646 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4647 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004648 }
4649
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004650#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004651/*
4652 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4653 * This function is used to notify the supplicant of a new PMKSA candidate.
4654 */
4655int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304656 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004657 int index, bool preauth )
4658{
Jeff Johnsone7245742012-09-05 17:12:55 -07004659#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004660 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004661 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004662
4663 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004664 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004665
4666 if( NULL == pRoamInfo )
4667 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004668 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004669 return -EINVAL;
4670 }
4671
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004672 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4673 {
4674 dump_bssid(pRoamInfo->bssid);
4675 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004676 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004677 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004678#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304679 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004680}
4681#endif //FEATURE_WLAN_LFR
4682
Yue Maef608272013-04-08 23:09:17 -07004683#ifdef FEATURE_WLAN_LFR_METRICS
4684/*
4685 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4686 * 802.11r/LFR metrics reporting function to report preauth initiation
4687 *
4688 */
4689#define MAX_LFR_METRICS_EVENT_LENGTH 100
4690VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4691 tCsrRoamInfo *pRoamInfo)
4692{
4693 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4694 union iwreq_data wrqu;
4695
4696 ENTER();
4697
4698 if (NULL == pAdapter)
4699 {
4700 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4701 return VOS_STATUS_E_FAILURE;
4702 }
4703
4704 /* create the event */
4705 memset(&wrqu, 0, sizeof(wrqu));
4706 memset(metrics_notification, 0, sizeof(metrics_notification));
4707
4708 wrqu.data.pointer = metrics_notification;
4709 wrqu.data.length = scnprintf(metrics_notification,
4710 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4711 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4712
4713 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4714
4715 EXIT();
4716
4717 return VOS_STATUS_SUCCESS;
4718}
4719
4720/*
4721 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4722 * 802.11r/LFR metrics reporting function to report preauth completion
4723 * or failure
4724 */
4725VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4726 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4727{
4728 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4729 union iwreq_data wrqu;
4730
4731 ENTER();
4732
4733 if (NULL == pAdapter)
4734 {
4735 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4736 return VOS_STATUS_E_FAILURE;
4737 }
4738
4739 /* create the event */
4740 memset(&wrqu, 0, sizeof(wrqu));
4741 memset(metrics_notification, 0, sizeof(metrics_notification));
4742
4743 scnprintf(metrics_notification, sizeof(metrics_notification),
4744 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4745 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4746
4747 if (1 == preauth_status)
4748 strncat(metrics_notification, " TRUE", 5);
4749 else
4750 strncat(metrics_notification, " FALSE", 6);
4751
4752 wrqu.data.pointer = metrics_notification;
4753 wrqu.data.length = strlen(metrics_notification);
4754
4755 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4756
4757 EXIT();
4758
4759 return VOS_STATUS_SUCCESS;
4760}
4761
4762/*
4763 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4764 * 802.11r/LFR metrics reporting function to report handover initiation
4765 *
4766 */
4767VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4768 tCsrRoamInfo *pRoamInfo)
4769{
4770 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4771 union iwreq_data wrqu;
4772
4773 ENTER();
4774
4775 if (NULL == pAdapter)
4776 {
4777 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4778 return VOS_STATUS_E_FAILURE;
4779 }
4780
4781 /* create the event */
4782 memset(&wrqu, 0, sizeof(wrqu));
4783 memset(metrics_notification, 0, sizeof(metrics_notification));
4784
4785 wrqu.data.pointer = metrics_notification;
4786 wrqu.data.length = scnprintf(metrics_notification,
4787 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4788 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4789
4790 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4791
4792 EXIT();
4793
4794 return VOS_STATUS_SUCCESS;
4795}
4796#endif
4797
Jeff Johnson295189b2012-06-20 16:38:30 -07004798/*
4799 * FUNCTION: hdd_cfg80211_scan_done_callback
4800 * scanning callback function, called after finishing scan
4801 *
4802 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304803static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004804 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4805{
4806 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304807 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004808 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004809 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4810 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004811 struct cfg80211_scan_request *req = NULL;
4812 int ret = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304813 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004814
4815 ENTER();
4816
4817 hddLog(VOS_TRACE_LEVEL_INFO,
4818 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004819 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004820 __func__, halHandle, pContext, (int) scanId, (int) status);
4821
Kiet Lamac06e2c2013-10-23 16:25:07 +05304822 pScanInfo->mScanPendingCounter = 0;
4823
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304825 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004826 &pScanInfo->scan_req_completion_event,
4827 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304828 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004829 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304830 hddLog(VOS_TRACE_LEVEL_ERROR,
4831 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004833 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 }
4835
Yue Maef608272013-04-08 23:09:17 -07004836 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004837 {
4838 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004839 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 }
4841
4842 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304843 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 {
4845 hddLog(VOS_TRACE_LEVEL_INFO,
4846 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004847 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 (int) scanId);
4849 }
4850
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304851 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 pAdapter);
4853
4854 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004856
4857
4858 /* If any client wait scan result through WEXT
4859 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004860 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004861 {
4862 /* The other scan request waiting for current scan finish
4863 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004864 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004866 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 }
4868 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004869 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004870 {
4871 struct net_device *dev = pAdapter->dev;
4872 union iwreq_data wrqu;
4873 int we_event;
4874 char *msg;
4875
4876 memset(&wrqu, '\0', sizeof(wrqu));
4877 we_event = SIOCGIWSCAN;
4878 msg = NULL;
4879 wireless_send_event(dev, we_event, &wrqu, msg);
4880 }
4881 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004882 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004883
4884 /* Get the Scan Req */
4885 req = pAdapter->request;
4886
4887 if (!req)
4888 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004889 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004890 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004891 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004892 }
4893
4894 /*
4895 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304896 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004897 req->n_ssids = 0;
4898 req->n_channels = 0;
4899 req->ie = 0;
4900
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004902 /* Scan is no longer pending */
4903 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004904
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004905 /*
4906 * cfg80211_scan_done informing NL80211 about completion
4907 * of scanning
4908 */
4909 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004910 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004911
Jeff Johnsone7245742012-09-05 17:12:55 -07004912allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004913 /* release the wake lock at the end of the scan*/
4914 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004915
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004916 /* Acquire wakelock to handle the case where APP's tries to suspend
4917 * immediatly after the driver gets connect request(i.e after scan)
4918 * from supplicant, this result in app's is suspending and not able
4919 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304920 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004921
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004922#ifdef FEATURE_WLAN_TDLS
4923 wlan_hdd_tdls_scan_done_callback(pAdapter);
4924#endif
4925
Jeff Johnson295189b2012-06-20 16:38:30 -07004926 EXIT();
4927 return 0;
4928}
4929
4930/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004931 * FUNCTION: hdd_isScanAllowed
4932 * Go through each adapter and check if scan allowed
4933 *
4934 */
4935v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4936{
4937 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4938 hdd_station_ctx_t *pHddStaCtx = NULL;
4939 hdd_adapter_t *pAdapter = NULL;
4940 VOS_STATUS status = 0;
4941 v_U8_t staId = 0;
4942 v_U8_t *staMac = NULL;
4943
c_hpothu9b781ba2013-12-30 20:57:45 +05304944 if (TRUE == pHddCtx->btCoexModeSet)
4945 {
4946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4947 FL("BTCoex Mode operation in progress, Do not allow scan"));
4948 return VOS_FALSE;
4949 }
4950
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004951 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4952
4953 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4954 {
4955 pAdapter = pAdapterNode->pAdapter;
4956
4957 if( pAdapter )
4958 {
4959 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304960 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004961 __func__, pAdapter->device_mode);
4962 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4963 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4964 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4965 {
4966 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4967 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4968 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4969 {
4970 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4971 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004972 "%s: client " MAC_ADDRESS_STR
4973 " is in the middle of WPS/EAPOL exchange.", __func__,
4974 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004975 return VOS_FALSE;
4976 }
4977 }
4978 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4979 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4980 {
4981 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304983 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004984 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4985 {
4986 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4987
4988 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004989 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
4990 "middle of WPS/EAPOL exchange.", __func__,
4991 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004992 return VOS_FALSE;
4993 }
4994 }
4995 }
4996 }
4997 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4998 pAdapterNode = pNext;
4999 }
5000 hddLog(VOS_TRACE_LEVEL_INFO,
5001 "%s: Scan allowed", __func__);
5002 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305003}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005004
5005/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005006 * FUNCTION: wlan_hdd_cfg80211_scan
5007 * this scan respond to scan trigger and update cfg80211 scan database
5008 * later, scan dump command can be used to recieve scan results
5009 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005010int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5011#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5012 struct net_device *dev,
5013#endif
5014 struct cfg80211_scan_request *request)
5015{
5016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5017 struct net_device *dev = request->wdev->netdev;
5018#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5021 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305022 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 tCsrScanRequest scanRequest;
5024 tANI_U8 *channelList = NULL, i;
5025 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305026 int status;
5027 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005029
5030 ENTER();
5031
Arif Hussain6d2a3322013-11-17 19:50:10 -08005032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005033 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005034
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305035 status = wlan_hdd_validate_context(pHddCtx);
5036
5037 if (0 != status)
5038 {
5039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5040 "%s: HDD context is not valid", __func__);
5041 return status;
5042 }
5043
5044 cfg_param = pHddCtx->cfg_ini;
5045 pScanInfo = &pHddCtx->scan_info;
5046
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005047 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005048 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005049 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005050 {
5051 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005052 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5053 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005054 return -EBUSY;
5055 }
5056
Jeff Johnson295189b2012-06-20 16:38:30 -07005057#ifdef WLAN_BTAMP_FEATURE
5058 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005059 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005060 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005061 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005062 "%s: No scanning when AMP is on", __func__);
5063 return -EOPNOTSUPP;
5064 }
5065#endif
5066 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005067 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005068 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005069 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 "%s: Not scanning on device_mode = %d",
5071 __func__, pAdapter->device_mode);
5072 return -EOPNOTSUPP;
5073 }
5074
5075 if (TRUE == pScanInfo->mScanPending)
5076 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305077 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5078 {
5079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5080 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005081 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 }
5083
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305084 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005085 //Channel and action frame is pending
5086 //Otherwise Cancel Remain On Channel and allow Scan
5087 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005088 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005089 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005091 return -EBUSY;
5092 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005093#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005094 /* if tdls disagree scan right now, return immediately.
5095 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5096 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5097 */
5098 status = wlan_hdd_tdls_scan_callback (pAdapter,
5099 wiphy,
5100#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5101 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005102#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005103 request);
5104 if(status <= 0)
5105 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305106 if(!status)
5107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5108 "scan rejected %d", __func__, status);
5109 else
5110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5111 __func__, status);
5112
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005113 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005114 }
5115#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005116
Jeff Johnson295189b2012-06-20 16:38:30 -07005117 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5118 {
5119 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005120 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005121 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305122 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5124 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305125 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 "%s: MAX TM Level Scan not allowed", __func__);
5127 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305128 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 }
5130 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5131
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005132 /* Check if scan is allowed at this point of time.
5133 */
5134 if (!hdd_isScanAllowed(pHddCtx))
5135 {
5136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5137 return -EBUSY;
5138 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305139
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5141
5142 if (NULL != request)
5143 {
5144 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305145 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005146
5147 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5148 * Becasue of this, driver is assuming that this is not wildcard scan and so
5149 * is not aging out the scan results.
5150 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005151 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 {
5153 request->n_ssids = 0;
5154 }
5155
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005156 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005157 {
5158 tCsrSSIDInfo *SsidInfo;
5159 int j;
5160 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5161 /* Allocate num_ssid tCsrSSIDInfo structure */
5162 SsidInfo = scanRequest.SSIDs.SSIDList =
5163 ( tCsrSSIDInfo *)vos_mem_malloc(
5164 request->n_ssids*sizeof(tCsrSSIDInfo));
5165
5166 if(NULL == scanRequest.SSIDs.SSIDList)
5167 {
5168 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305169 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005170 return -ENOMEM;
5171 }
5172
5173 /* copy all the ssid's and their length */
5174 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5175 {
5176 /* get the ssid length */
5177 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5178 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5179 SsidInfo->SSID.length);
5180 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305181 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005182 j, SsidInfo->SSID.ssId);
5183 }
5184 /* set the scan type to active */
5185 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5186 }
5187 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5188 {
5189 /* set the scan type to active */
5190 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5191 }
5192 else
5193 {
5194 /*Set the scan type to default type, in this case it is ACTIVE*/
5195 scanRequest.scanType = pScanInfo->scan_mode;
5196 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305197 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5199 }
5200 else
5201 {
5202 /* set the scan type to active */
5203 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5204 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5205
5206 /* set min and max channel time to zero */
5207 scanRequest.minChnTime = 0;
5208 scanRequest.maxChnTime = 0;
5209 }
5210
5211 /* set BSSType to default type */
5212 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5213
5214 /*TODO: scan the requested channels only*/
5215
5216 /*Right now scanning all the channels */
5217 if( request )
5218 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305219 hddLog(VOS_TRACE_LEVEL_INFO,
5220 "No of Scan Channels: %d", request->n_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07005221 if( request->n_channels )
5222 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305223 char chList [(request->n_channels*5)+1];
5224 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005225 channelList = vos_mem_malloc( request->n_channels );
5226 if( NULL == channelList )
5227 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305228 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305229 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 status = -ENOMEM;
5231 goto free_mem;
5232 }
5233
Nirav Shah20ac06f2013-12-12 18:14:06 +05305234 for( i = 0, len = 0; i < request->n_channels ; i++ )
5235 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305237 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5238 }
5239
5240 hddLog(VOS_TRACE_LEVEL_INFO,
5241 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 }
5243
5244 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5245 scanRequest.ChannelInfo.ChannelList = channelList;
5246
5247 /* set requestType to full scan */
5248 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305249
5250 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005251 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305252 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005253 */
5254
5255 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305256 * and in that case driver shoudnt flush scan results. If
5257 * driver flushes the scan results here and unfortunately if
5258 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005259 * fails which is not desired
5260 */
5261
5262 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5263 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305264 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005265 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5266 pAdapter->sessionId );
5267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005268
5269 if( request->ie_len )
5270 {
5271 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305272 /*TODO: Array needs to be converted to dynamic allocation,
5273 * as multiple ie.s can be sent in cfg80211_scan_request structure
5274 * CR 597966
5275 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005276 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5277 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5278 pScanInfo->scanAddIE.length = request->ie_len;
5279
Agarwal Ashish4f616132013-12-30 23:32:50 +05305280 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005281 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305282 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005283 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305284 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5285 {
5286 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5287 memcpy( pwextBuf->roamProfile.addIEScan,
5288 request->ie, request->ie_len);
5289 }
5290 else
5291 {
5292 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5293 "%d", request->ie_len);
5294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005295
Agarwal Ashish4f616132013-12-30 23:32:50 +05305296 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5298 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5299
Jeff Johnson295189b2012-06-20 16:38:30 -07005300 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5301 request->ie_len);
5302 if (pP2pIe != NULL)
5303 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005304#ifdef WLAN_FEATURE_P2P_DEBUG
5305 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5306 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5307 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5308 {
5309 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5310 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5311 "Go nego completed to Connection is started");
5312 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5313 "for 8way Handshake");
5314 }
5315 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5316 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5317 {
5318 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5319 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5320 "Disconnected state to Connection is started");
5321 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5322 "for 4way Handshake");
5323 }
5324#endif
5325
Jeff Johnsone7245742012-09-05 17:12:55 -07005326 /* no_cck will be set during p2p find to disable 11b rates */
5327 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005328 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005329 hddLog(VOS_TRACE_LEVEL_INFO,
5330 "%s: This is a P2P Search", __func__);
5331 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005332
Jeff Johnsone7245742012-09-05 17:12:55 -07005333 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5334 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005335 /* set requestType to P2P Discovery */
5336 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005337 }
5338
5339 /*
5340 Skip Dfs Channel in case of P2P Search
5341 if it is set in ini file
5342 */
5343 if(cfg_param->skipDfsChnlInP2pSearch)
5344 {
5345 scanRequest.skipDfsChnlInP2pSearch = 1;
5346 }
5347 else
5348 {
5349 scanRequest.skipDfsChnlInP2pSearch = 0;
5350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005351
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 }
5353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 }
5355 }
5356
5357 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5358
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005359 /* acquire the wakelock to avoid the apps suspend during the scan. To
5360 * address the following issues.
5361 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5362 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5363 * for long time, this result in apps running at full power for long time.
5364 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5365 * be stuck in full power because of resume BMPS
5366 */
5367 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005368
Nirav Shah20ac06f2013-12-12 18:14:06 +05305369 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5370 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5371 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5372 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5373 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5374
Jeff Johnsone7245742012-09-05 17:12:55 -07005375 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 pAdapter->sessionId, &scanRequest, &scanId,
5377 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005378
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 if (eHAL_STATUS_SUCCESS != status)
5380 {
5381 hddLog(VOS_TRACE_LEVEL_ERROR,
5382 "%s: sme_ScanRequest returned error %d", __func__, status);
5383 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005384 if(eHAL_STATUS_RESOURCES == status)
5385 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5387 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005388 status = -EBUSY;
5389 } else {
5390 status = -EIO;
5391 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005392 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 goto free_mem;
5394 }
5395
5396 pScanInfo->mScanPending = TRUE;
5397 pAdapter->request = request;
5398 pScanInfo->scanId = scanId;
5399
5400 complete(&pScanInfo->scan_req_completion_event);
5401
5402free_mem:
5403 if( scanRequest.SSIDs.SSIDList )
5404 {
5405 vos_mem_free(scanRequest.SSIDs.SSIDList);
5406 }
5407
5408 if( channelList )
5409 vos_mem_free( channelList );
5410
5411 EXIT();
5412
5413 return status;
5414}
5415
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005416
5417void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5418{
5419 v_U8_t iniDot11Mode =
5420 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5421 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5422
5423 switch ( iniDot11Mode )
5424 {
5425 case eHDD_DOT11_MODE_AUTO:
5426 case eHDD_DOT11_MODE_11ac:
5427 case eHDD_DOT11_MODE_11ac_ONLY:
5428#ifdef WLAN_FEATURE_11AC
5429 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5430#else
5431 hddDot11Mode = eHDD_DOT11_MODE_11n;
5432#endif
5433 break;
5434 case eHDD_DOT11_MODE_11n:
5435 case eHDD_DOT11_MODE_11n_ONLY:
5436 hddDot11Mode = eHDD_DOT11_MODE_11n;
5437 break;
5438 default:
5439 hddDot11Mode = iniDot11Mode;
5440 break;
5441 }
5442 /* This call decides required channel bonding mode */
5443 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5444 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5445 operationChannel);
5446}
5447
Jeff Johnson295189b2012-06-20 16:38:30 -07005448/*
5449 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305450 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305452int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005453 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005454{
5455 int status = 0;
5456 hdd_wext_state_t *pWextState;
5457 v_U32_t roamId;
5458 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 eCsrAuthType RSNAuthType;
5460
5461 ENTER();
5462
5463 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305464
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5466 {
5467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5468 return -EINVAL;
5469 }
5470
5471 pRoamProfile = &pWextState->roamProfile;
5472
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305473 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005475 hdd_station_ctx_t *pHddStaCtx;
5476 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005477
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305478 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5480 {
5481 /*QoS not enabled in cfg file*/
5482 pRoamProfile->uapsd_mask = 0;
5483 }
5484 else
5485 {
5486 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5489 }
5490
5491 pRoamProfile->SSIDs.numOfSSIDs = 1;
5492 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5493 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305494 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5496 ssid, ssid_len);
5497
5498 if (bssid)
5499 {
5500 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5501 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5502 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503 /* Save BSSID in seperate variable as well, as RoamProfile
5504 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005505 case of join failure we should send valid BSSID to supplicant
5506 */
5507 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5508 WNI_CFG_BSSID_LEN);
5509 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005510 else
5511 {
5512 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005514
5515 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5516 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305517 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 /*set gen ie*/
5519 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5520 /*set auth*/
5521 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5522 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005523#ifdef FEATURE_WLAN_WAPI
5524 if (pAdapter->wapi_info.nWapiMode)
5525 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005526 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 switch (pAdapter->wapi_info.wapiAuthMode)
5528 {
5529 case WAPI_AUTH_MODE_PSK:
5530 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005531 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 pAdapter->wapi_info.wapiAuthMode);
5533 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5534 break;
5535 }
5536 case WAPI_AUTH_MODE_CERT:
5537 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005538 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 pAdapter->wapi_info.wapiAuthMode);
5540 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5541 break;
5542 }
5543 } // End of switch
5544 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5545 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5546 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005547 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 pRoamProfile->AuthType.numEntries = 1;
5549 pRoamProfile->EncryptionType.numEntries = 1;
5550 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5551 pRoamProfile->mcEncryptionType.numEntries = 1;
5552 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5553 }
5554 }
5555#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305556#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305557 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305558 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5559 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5560 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305561 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5562 sizeof (tSirGtkOffloadParams));
5563 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305564 }
5565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 pRoamProfile->csrPersona = pAdapter->device_mode;
5567
Jeff Johnson32d95a32012-09-10 13:15:23 -07005568 if( operatingChannel )
5569 {
5570 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5571 pRoamProfile->ChannelInfo.numOfChannels = 1;
5572 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005573 else
5574 {
5575 pRoamProfile->ChannelInfo.ChannelList = NULL;
5576 pRoamProfile->ChannelInfo.numOfChannels = 0;
5577 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005578 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5579 {
5580 hdd_select_cbmode(pAdapter,operatingChannel);
5581 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005582 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5583 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305584 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005585 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005586 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5587 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305588 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5589 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005590 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5591 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305592
5593 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 pAdapter->sessionId, pRoamProfile, &roamId);
5595
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305596 if ((eHAL_STATUS_SUCCESS != status) &&
5597 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5598 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305599
5600 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5602 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5603 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305604 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005605 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305606 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005607
5608 pRoamProfile->ChannelInfo.ChannelList = NULL;
5609 pRoamProfile->ChannelInfo.numOfChannels = 0;
5610
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 }
5612 else
5613 {
5614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5615 return -EINVAL;
5616 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005617 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 return status;
5619}
5620
5621/*
5622 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5623 * This function is used to set the authentication type (OPEN/SHARED).
5624 *
5625 */
5626static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5627 enum nl80211_auth_type auth_type)
5628{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305629 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005630 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5631
5632 ENTER();
5633
5634 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305635 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305638 hddLog(VOS_TRACE_LEVEL_INFO,
5639 "%s: set authentication type to AUTOSWITCH", __func__);
5640 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5641 break;
5642
5643 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005644#ifdef WLAN_FEATURE_VOWIFI_11R
5645 case NL80211_AUTHTYPE_FT:
5646#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305647 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 "%s: set authentication type to OPEN", __func__);
5649 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5650 break;
5651
5652 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305653 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 "%s: set authentication type to SHARED", __func__);
5655 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5656 break;
5657#ifdef FEATURE_WLAN_CCX
5658 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305659 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 "%s: set authentication type to CCKM WPA", __func__);
5661 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5662 break;
5663#endif
5664
5665
5666 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305667 hddLog(VOS_TRACE_LEVEL_ERROR,
5668 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 auth_type);
5670 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5671 return -EINVAL;
5672 }
5673
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305674 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005675 pHddStaCtx->conn_info.authType;
5676 return 0;
5677}
5678
5679/*
5680 * FUNCTION: wlan_hdd_set_akm_suite
5681 * This function is used to set the key mgmt type(PSK/8021x).
5682 *
5683 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305684static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 u32 key_mgmt
5686 )
5687{
5688 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5689 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305690
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 /*set key mgmt type*/
5692 switch(key_mgmt)
5693 {
5694 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305695#ifdef WLAN_FEATURE_VOWIFI_11R
5696 case WLAN_AKM_SUITE_FT_PSK:
5697#endif
5698 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 __func__);
5700 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5701 break;
5702
5703 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305704#ifdef WLAN_FEATURE_VOWIFI_11R
5705 case WLAN_AKM_SUITE_FT_8021X:
5706#endif
5707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005708 __func__);
5709 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5710 break;
5711#ifdef FEATURE_WLAN_CCX
5712#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5713#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5714 case WLAN_AKM_SUITE_CCKM:
5715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5716 __func__);
5717 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5718 break;
5719#endif
5720
5721 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 __func__, key_mgmt);
5724 return -EINVAL;
5725
5726 }
5727 return 0;
5728}
5729
5730/*
5731 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305732 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 * (NONE/WEP40/WEP104/TKIP/CCMP).
5734 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305735static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5736 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 bool ucast
5738 )
5739{
5740 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5743
5744 ENTER();
5745
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305746 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 __func__, cipher);
5750 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5751 }
5752 else
5753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305756 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 {
5758 case IW_AUTH_CIPHER_NONE:
5759 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5760 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305761
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305763 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305765
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305767 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305769
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 case WLAN_CIPHER_SUITE_TKIP:
5771 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5772 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305773
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 case WLAN_CIPHER_SUITE_CCMP:
5775 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5776 break;
5777#ifdef FEATURE_WLAN_WAPI
5778 case WLAN_CIPHER_SUITE_SMS4:
5779 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5780 break;
5781#endif
5782
5783#ifdef FEATURE_WLAN_CCX
5784 case WLAN_CIPHER_SUITE_KRK:
5785 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5786 break;
5787#endif
5788 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 __func__, cipher);
5791 return -EOPNOTSUPP;
5792 }
5793 }
5794
5795 if (ucast)
5796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 __func__, encryptionType);
5799 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5800 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305801 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 encryptionType;
5803 }
5804 else
5805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305806 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 __func__, encryptionType);
5808 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5809 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5810 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5811 }
5812
5813 return 0;
5814}
5815
5816
5817/*
5818 * FUNCTION: wlan_hdd_cfg80211_set_ie
5819 * This function is used to parse WPA/RSN IE's.
5820 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305821int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5822 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 size_t ie_len
5824 )
5825{
5826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5827 u8 *genie = ie;
5828 v_U16_t remLen = ie_len;
5829#ifdef FEATURE_WLAN_WAPI
5830 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5831 u16 *tmp;
5832 v_U16_t akmsuiteCount;
5833 int *akmlist;
5834#endif
5835 ENTER();
5836
5837 /* clear previous assocAddIE */
5838 pWextState->assocAddIE.length = 0;
5839 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5840
5841 while (remLen >= 2)
5842 {
5843 v_U16_t eLen = 0;
5844 v_U8_t elementId;
5845 elementId = *genie++;
5846 eLen = *genie++;
5847 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305848
Arif Hussain6d2a3322013-11-17 19:50:10 -08005849 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305851
5852 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305854 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005855 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 -07005856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305857 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 "%s: Invalid WPA IE", __func__);
5859 return -EINVAL;
5860 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 {
5863 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5868 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005869 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5870 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 VOS_ASSERT(0);
5872 return -ENOMEM;
5873 }
5874 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5875 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5876 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305877
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5879 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5880 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5881 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305882 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5883 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5885 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5886 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5887 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5888 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5889 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305890 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305891 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 {
5893 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305896
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5898 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005899 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5900 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 VOS_ASSERT(0);
5902 return -ENOMEM;
5903 }
5904 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5905 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5906 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305907
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5909 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005911#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305912 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5913 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 /*Consider WFD IE, only for P2P Client */
5915 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5916 {
5917 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305918 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5922 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005923 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5924 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 VOS_ASSERT(0);
5926 return -ENOMEM;
5927 }
5928 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5929 // WPS IE + P2P IE + WFD IE
5930 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5931 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305932
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5934 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5935 }
5936#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005937 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305938 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005939 HS20_OUI_TYPE_SIZE)) )
5940 {
5941 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305942 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005943 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005944
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005945 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5946 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005947 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5948 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005949 VOS_ASSERT(0);
5950 return -ENOMEM;
5951 }
5952 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5953 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005954
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005955 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5956 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5957 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005958
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07005959 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
5960
5961 /* populating as ADDIE in beacon frames */
5962 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5963 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
5964 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
5965 {
5966 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5967 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5968 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5969 {
5970 hddLog(LOGE,
5971 "Coldn't pass "
5972 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
5973 }
5974 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
5975 else
5976 hddLog(LOGE,
5977 "Could not pass on "
5978 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
5979
5980 /* IBSS mode doesn't contain params->proberesp_ies still
5981 beaconIE's need to be populated in probe response frames */
5982 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
5983 {
5984 u16 rem_probe_resp_ie_len = eLen + 2;
5985 u8 probe_rsp_ie_len[3] = {0};
5986 u8 counter = 0;
5987
5988 /* Check Probe Resp Length if it is greater then 255 then
5989 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
5990 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
5991 not able Store More then 255 bytes into One Variable */
5992
5993 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5994 {
5995 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5996 {
5997 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5998 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5999 }
6000 else
6001 {
6002 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6003 rem_probe_resp_ie_len = 0;
6004 }
6005 }
6006
6007 rem_probe_resp_ie_len = 0;
6008
6009 if (probe_rsp_ie_len[0] > 0)
6010 {
6011 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6012 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6013 (tANI_U8*)(genie - 2),
6014 probe_rsp_ie_len[0], NULL,
6015 eANI_BOOLEAN_FALSE)
6016 == eHAL_STATUS_FAILURE)
6017 {
6018 hddLog(LOGE,
6019 "Could not pass"
6020 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6021 }
6022 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6023 }
6024
6025 if (probe_rsp_ie_len[1] > 0)
6026 {
6027 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6028 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6029 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6030 probe_rsp_ie_len[1], NULL,
6031 eANI_BOOLEAN_FALSE)
6032 == eHAL_STATUS_FAILURE)
6033 {
6034 hddLog(LOGE,
6035 "Could not pass"
6036 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6037 }
6038 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6039 }
6040
6041 if (probe_rsp_ie_len[2] > 0)
6042 {
6043 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6044 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6045 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6046 probe_rsp_ie_len[2], NULL,
6047 eANI_BOOLEAN_FALSE)
6048 == eHAL_STATUS_FAILURE)
6049 {
6050 hddLog(LOGE,
6051 "Could not pass"
6052 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6053 }
6054 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6055 }
6056
6057 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6058 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6059 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6060 {
6061 hddLog(LOGE,
6062 "Could not pass"
6063 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6064 }
6065 }
6066 else
6067 {
6068 // Reset WNI_CFG_PROBE_RSP Flags
6069 wlan_hdd_reset_prob_rspies(pAdapter);
6070
6071 hddLog(VOS_TRACE_LEVEL_INFO,
6072 "%s: No Probe Response IE received in set beacon",
6073 __func__);
6074 }
6075 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 break;
6077 case DOT11F_EID_RSN:
6078 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6079 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6080 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6081 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6082 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6083 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006084 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6085 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306086 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006087 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006089 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306090
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006091 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6092 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006093 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6094 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006095 VOS_ASSERT(0);
6096 return -ENOMEM;
6097 }
6098 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6099 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306100
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006101 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6102 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6103 break;
6104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006105#ifdef FEATURE_WLAN_WAPI
6106 case WLAN_EID_WAPI:
6107 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006108 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 pAdapter->wapi_info.nWapiMode);
6110 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306111 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 akmsuiteCount = WPA_GET_LE16(tmp);
6113 tmp = tmp + 1;
6114 akmlist = (int *)(tmp);
6115 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6116 {
6117 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6118 }
6119 else
6120 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006121 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 VOS_ASSERT(0);
6123 return -EINVAL;
6124 }
6125
6126 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6127 {
6128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006129 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306131 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306133 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006135 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6137 }
6138 break;
6139#endif
6140 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306141 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006143 /* when Unknown IE is received we should break and continue
6144 * to the next IE in the buffer instead we were returning
6145 * so changing this to break */
6146 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 }
6148 genie += eLen;
6149 remLen -= eLen;
6150 }
6151 EXIT();
6152 return 0;
6153}
6154
6155/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306156 * FUNCTION: hdd_isWPAIEPresent
6157 * Parse the received IE to find the WPA IE
6158 *
6159 */
6160static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6161{
6162 v_U8_t eLen = 0;
6163 v_U16_t remLen = ie_len;
6164 v_U8_t elementId = 0;
6165
6166 while (remLen >= 2)
6167 {
6168 elementId = *ie++;
6169 eLen = *ie++;
6170 remLen -= 2;
6171 if (eLen > remLen)
6172 {
6173 hddLog(VOS_TRACE_LEVEL_ERROR,
6174 "%s: IE length is wrong %d", __func__, eLen);
6175 return FALSE;
6176 }
6177 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6178 {
6179 /* OUI - 0x00 0X50 0XF2
6180 WPA Information Element - 0x01
6181 WPA version - 0x01*/
6182 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6183 return TRUE;
6184 }
6185 ie += eLen;
6186 remLen -= eLen;
6187 }
6188 return FALSE;
6189}
6190
6191/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306193 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 * parameters during connect operation.
6195 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306196int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 struct cfg80211_connect_params *req
6198 )
6199{
6200 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306201 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 ENTER();
6203
6204 /*set wpa version*/
6205 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6206
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306207 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306209 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 {
6211 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6212 }
6213 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6214 {
6215 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6216 }
6217 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306218
6219 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 pWextState->wpaVersion);
6221
6222 /*set authentication type*/
6223 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6224
6225 if (0 > status)
6226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306227 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 "%s: failed to set authentication type ", __func__);
6229 return status;
6230 }
6231
6232 /*set key mgmt type*/
6233 if (req->crypto.n_akm_suites)
6234 {
6235 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6236 if (0 > status)
6237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306238 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 __func__);
6240 return status;
6241 }
6242 }
6243
6244 /*set pairwise cipher type*/
6245 if (req->crypto.n_ciphers_pairwise)
6246 {
6247 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6248 req->crypto.ciphers_pairwise[0], true);
6249 if (0 > status)
6250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306251 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 "%s: failed to set unicast cipher type", __func__);
6253 return status;
6254 }
6255 }
6256 else
6257 {
6258 /*Reset previous cipher suite to none*/
6259 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6260 if (0 > status)
6261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306262 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 "%s: failed to set unicast cipher type", __func__);
6264 return status;
6265 }
6266 }
6267
6268 /*set group cipher type*/
6269 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6270 false);
6271
6272 if (0 > status)
6273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 __func__);
6276 return status;
6277 }
6278
Chet Lanctot186b5732013-03-18 10:26:30 -07006279#ifdef WLAN_FEATURE_11W
6280 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6281#endif
6282
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6284 if (req->ie_len)
6285 {
6286 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6287 if ( 0 > status)
6288 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 __func__);
6291 return status;
6292 }
6293 }
6294
6295 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306296 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006297 {
6298 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6299 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6300 )
6301 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306302 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6304 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 __func__);
6307 return -EOPNOTSUPP;
6308 }
6309 else
6310 {
6311 u8 key_len = req->key_len;
6312 u8 key_idx = req->key_idx;
6313
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306314 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 && (CSR_MAX_NUM_KEY > key_idx)
6316 )
6317 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318 hddLog(VOS_TRACE_LEVEL_INFO,
6319 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 __func__, key_idx, key_len);
6321 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306322 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306324 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 (u8)key_len;
6326 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6327 }
6328 }
6329 }
6330 }
6331
6332 return status;
6333}
6334
6335/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306336 * FUNCTION: wlan_hdd_try_disconnect
6337 * This function is used to disconnect from previous
6338 * connection
6339 */
6340static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6341{
6342 long ret = 0;
6343 hdd_station_ctx_t *pHddStaCtx;
6344 eMib_dot11DesiredBssType connectedBssType;
6345
6346 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6347
6348 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6349
6350 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6351 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6352 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6353 {
6354 /* Issue disconnect to CSR */
6355 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6356 if( eHAL_STATUS_SUCCESS ==
6357 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6358 pAdapter->sessionId,
6359 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6360 {
6361 ret = wait_for_completion_interruptible_timeout(
6362 &pAdapter->disconnect_comp_var,
6363 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6364 if (0 >= ret)
6365 {
6366 hddLog(LOGE, FL("Failed to receive disconnect event"));
6367 return -EALREADY;
6368 }
6369 }
6370 }
6371 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6372 {
6373 ret = wait_for_completion_interruptible_timeout(
6374 &pAdapter->disconnect_comp_var,
6375 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6376 if (0 >= ret)
6377 {
6378 hddLog(LOGE, FL("Failed to receive disconnect event"));
6379 return -EALREADY;
6380 }
6381 }
6382
6383 return 0;
6384}
6385
6386/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306388 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 * parameters during connect operation.
6390 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306391static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 struct net_device *ndev,
6393 struct cfg80211_connect_params *req
6394 )
6395{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306396 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006398 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006399 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006400
6401 ENTER();
6402
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006403 if (!pAdapter)
6404 {
6405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6406 "%s: Adapter context is null", __func__);
6407 return VOS_STATUS_E_FAILURE;
6408 }
6409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306410 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006411 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006412
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306413 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006414 if (!pHddCtx)
6415 {
6416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6417 "%s: HDD context is null", __func__);
6418 return VOS_STATUS_E_FAILURE;
6419 }
6420
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306421 status = wlan_hdd_validate_context(pHddCtx);
6422
6423 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6426 "%s: HDD context is not valid", __func__);
6427 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 }
6429
6430#ifdef WLAN_BTAMP_FEATURE
6431 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306432 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306434 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006436 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 }
6438#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306439
6440 //If Device Mode is Station Concurrent Sessions Exit BMps
6441 //P2P Mode will be taken care in Open/close adapter
6442 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6443 (vos_concurrent_sessions_running()))
6444 {
6445 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6446 }
6447
6448 /*Try disconnecting if already in connected state*/
6449 status = wlan_hdd_try_disconnect(pAdapter);
6450 if ( 0 > status)
6451 {
6452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6453 " connection"));
6454 return -EALREADY;
6455 }
6456
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006459
6460 if ( 0 > status)
6461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006463 __func__);
6464 return status;
6465 }
6466
Mohit Khanna765234a2012-09-11 15:08:35 -07006467 if ( req->channel )
6468 {
6469 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6470 req->ssid_len, req->bssid,
6471 req->channel->hw_value);
6472 }
6473 else
6474 {
6475 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306476 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006477 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006478
6479 if (0 > status)
6480 {
6481 //ReEnable BMPS if disabled
6482 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6483 (NULL != pHddCtx))
6484 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306485 if (pHddCtx->hdd_wlan_suspended)
6486 {
6487 hdd_set_pwrparams(pHddCtx);
6488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 //ReEnable Bmps and Imps back
6490 hdd_enable_bmps_imps(pHddCtx);
6491 }
6492
6493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6494 return status;
6495 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306496 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006497 EXIT();
6498 return status;
6499}
6500
6501
6502/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306503 * FUNCTION: wlan_hdd_disconnect
6504 * This function is used to issue a disconnect request to SME
6505 */
6506int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6507{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306508 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306509 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306510 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306511 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306512
6513 status = wlan_hdd_validate_context(pHddCtx);
6514
6515 if (0 != status)
6516 {
6517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6518 "%s: HDD context is not valid", __func__);
6519 return status;
6520 }
6521
6522 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306523 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306524 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306525
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306526 /*issue disconnect*/
6527 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6528 pAdapter->sessionId, reason);
6529
6530 if ( 0 != status )
6531 {
6532 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006533 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306534 __func__, (int)status );
6535 return -EINVAL;
6536 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306537 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306538 &pAdapter->disconnect_comp_var,
6539 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306540 if (ret <= 0)
6541 {
6542 hddLog(VOS_TRACE_LEVEL_ERROR,
6543 FL("wait on disconnect_comp_var failed %ld"), ret);
6544 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306545 /*stop tx queues*/
6546 netif_tx_disable(pAdapter->dev);
6547 netif_carrier_off(pAdapter->dev);
6548 return status;
6549}
6550
6551
6552/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006553 * FUNCTION: wlan_hdd_cfg80211_disconnect
6554 * This function is used to issue a disconnect request to SME
6555 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306556static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006557 struct net_device *dev,
6558 u16 reason
6559 )
6560{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306561 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6562 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306564 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006566 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306567#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006568 tANI_U8 staIdx;
6569#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306572
Arif Hussain6d2a3322013-11-17 19:50:10 -08006573 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 __func__,pAdapter->device_mode);
6575
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6577 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006578
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306579 status = wlan_hdd_validate_context(pHddCtx);
6580
6581 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006582 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6584 "%s: HDD context is not valid", __func__);
6585 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306587
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 if (NULL != pRoamProfile)
6589 {
6590 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306591 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6592 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306594 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306596 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 switch(reason)
6598 {
6599 case WLAN_REASON_MIC_FAILURE:
6600 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6601 break;
6602
6603 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6604 case WLAN_REASON_DISASSOC_AP_BUSY:
6605 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6606 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6607 break;
6608
6609 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6610 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6611 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6612 break;
6613
6614 case WLAN_REASON_DEAUTH_LEAVING:
6615 default:
6616 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6617 break;
6618 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306619 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6620 pScanInfo = &pHddCtx->scan_info;
6621 if (pScanInfo->mScanPending)
6622 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306623 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306624 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306625 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6626 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006628
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006629#ifdef FEATURE_WLAN_TDLS
6630 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006631 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006632 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006633 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6634 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006635 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006636 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006637 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006638 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006639 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006640 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006641 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006642 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006643 pAdapter->sessionId,
6644 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006645 }
6646 }
6647#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306648 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6649 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 {
6651 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006652 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 __func__, (int)status );
6654 return -EINVAL;
6655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306657 else
6658 {
6659 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6660 "called while in %d state", __func__,
6661 pHddStaCtx->conn_info.connState);
6662 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006663 }
6664 else
6665 {
6666 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6667 }
6668
6669 return status;
6670}
6671
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306672
Jeff Johnson295189b2012-06-20 16:38:30 -07006673/*
6674 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306675 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 * settings in IBSS mode.
6677 */
6678static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306679 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006680 struct cfg80211_ibss_params *params
6681 )
6682{
6683 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306684 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006685 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6686 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306687
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 ENTER();
6689
6690 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006691 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006692
6693 if (params->ie_len && ( NULL != params->ie) )
6694 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006695 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6696 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 {
6698 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6699 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6700 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006701 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006703 tDot11fIEWPA dot11WPAIE;
6704 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006705 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006706
Wilson Yang00256342013-10-10 23:13:38 -07006707 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006708 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6709 params->ie_len, DOT11F_EID_WPA);
6710 if ( NULL != ie )
6711 {
6712 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6713 // Unpack the WPA IE
6714 //Skip past the EID byte and length byte - and four byte WiFi OUI
6715 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6716 &ie[2+4],
6717 ie[1] - 4,
6718 &dot11WPAIE);
6719 /*Extract the multicast cipher, the encType for unicast
6720 cipher for wpa-none is none*/
6721 encryptionType =
6722 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006725
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6727
6728 if (0 > status)
6729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006731 __func__);
6732 return status;
6733 }
6734 }
6735
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306736 pWextState->roamProfile.AuthType.authType[0] =
6737 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6739
6740 if (params->privacy)
6741 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306742 /* Security enabled IBSS, At this time there is no information available
6743 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006744 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306745 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306747 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 *enable privacy bit in beacons */
6749
6750 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6751 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006752 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6753 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6755 pWextState->roamProfile.EncryptionType.numEntries = 1;
6756 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 return status;
6758}
6759
6760/*
6761 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306762 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 struct net_device *dev,
6766 struct cfg80211_ibss_params *params
6767 )
6768{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306769 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6771 tCsrRoamProfile *pRoamProfile;
6772 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006773 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306775 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
6777 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306778
6779 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006780 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006781
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306782 status = wlan_hdd_validate_context(pHddCtx);
6783
6784 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6787 "%s: HDD context is not valid", __func__);
6788 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 }
6790
6791 if (NULL == pWextState)
6792 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006793 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 __func__);
6795 return -EIO;
6796 }
6797
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306798 /*Try disconnecting if already in connected state*/
6799 status = wlan_hdd_try_disconnect(pAdapter);
6800 if ( 0 > status)
6801 {
6802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6803 " IBSS connection"));
6804 return -EALREADY;
6805 }
6806
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 pRoamProfile = &pWextState->roamProfile;
6808
6809 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306811 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006812 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 return -EINVAL;
6814 }
6815
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006816 /* BSSID is provided by upper layers hence no need to AUTO generate */
6817 if (NULL != params->bssid) {
6818 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6819 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6820 hddLog (VOS_TRACE_LEVEL_ERROR,
6821 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6822 return -EIO;
6823 }
6824 }
krunal sonie9002db2013-11-25 14:24:17 -08006825 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6826 {
6827 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6828 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6829 {
6830 hddLog (VOS_TRACE_LEVEL_ERROR,
6831 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6832 return -EIO;
6833 }
6834 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6835 if (!params->bssid)
6836 {
6837 hddLog (VOS_TRACE_LEVEL_ERROR,
6838 "%s:Failed memory allocation", __func__);
6839 return -EIO;
6840 }
6841 vos_mem_copy((v_U8_t *)params->bssid,
6842 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6843 VOS_MAC_ADDR_SIZE);
6844 alloc_bssid = VOS_TRUE;
6845 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006846
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006848 if (NULL !=
6849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6850 params->chandef.chan)
6851#else
6852 params->channel)
6853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 {
6855 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006856 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6857 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6858 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6859 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006860
6861 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306862 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006863 ieee80211_frequency_to_channel(
6864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6865 params->chandef.chan->center_freq);
6866#else
6867 params->channel->center_freq);
6868#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006869
6870 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6871 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6874 __func__);
6875 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006877
6878 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006880 if (channelNum == validChan[indx])
6881 {
6882 break;
6883 }
6884 }
6885 if (indx >= numChans)
6886 {
6887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 __func__, channelNum);
6889 return -EINVAL;
6890 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006891 /* Set the Operational Channel */
6892 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6893 channelNum);
6894 pRoamProfile->ChannelInfo.numOfChannels = 1;
6895 pHddStaCtx->conn_info.operationChannel = channelNum;
6896 pRoamProfile->ChannelInfo.ChannelList =
6897 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 }
6899
6900 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 if (status < 0)
6903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 __func__);
6906 return status;
6907 }
6908
6909 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006911 params->ssid_len, params->bssid,
6912 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006913
6914 if (0 > status)
6915 {
6916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6917 return status;
6918 }
6919
krunal sonie9002db2013-11-25 14:24:17 -08006920 if (NULL != params->bssid &&
6921 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
6922 alloc_bssid == VOS_TRUE)
6923 {
6924 vos_mem_free(params->bssid);
6925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 return 0;
6927}
6928
6929/*
6930 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306933static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 struct net_device *dev
6935 )
6936{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6939 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306940 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6941 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006942
6943 ENTER();
6944
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306945 status = wlan_hdd_validate_context(pHddCtx);
6946
6947 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006948 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6950 "%s: HDD context is not valid", __func__);
6951 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006952 }
6953
Arif Hussain6d2a3322013-11-17 19:50:10 -08006954 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 if (NULL == pWextState)
6956 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006957 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 __func__);
6959 return -EIO;
6960 }
6961
6962 pRoamProfile = &pWextState->roamProfile;
6963
6964 /* Issue disconnect only if interface type is set to IBSS */
6965 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6966 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306967 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 __func__);
6969 return -EINVAL;
6970 }
6971
6972 /* Issue Disconnect request */
6973 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6974 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6975 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6976
6977 return 0;
6978}
6979
6980/*
6981 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6982 * This function is used to set the phy parameters
6983 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6984 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306985static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006986 u32 changed)
6987{
6988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6989 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306990 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006991
6992 ENTER();
6993
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306994 status = wlan_hdd_validate_context(pHddCtx);
6995
6996 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006997 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6999 "%s: HDD context is not valid", __func__);
7000 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007001 }
7002
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7004 {
7005 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7006 WNI_CFG_RTS_THRESHOLD_STAMAX :
7007 wiphy->rts_threshold;
7008
7009 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307010 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307012 hddLog(VOS_TRACE_LEVEL_ERROR,
7013 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 __func__, rts_threshold);
7015 return -EINVAL;
7016 }
7017
7018 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7019 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307020 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307022 hddLog(VOS_TRACE_LEVEL_ERROR,
7023 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 __func__, rts_threshold);
7025 return -EIO;
7026 }
7027
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307028 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 rts_threshold);
7030 }
7031
7032 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7033 {
7034 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7035 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7036 wiphy->frag_threshold;
7037
7038 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307039 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307041 hddLog(VOS_TRACE_LEVEL_ERROR,
7042 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 frag_threshold);
7044 return -EINVAL;
7045 }
7046
7047 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7048 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307049 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307051 hddLog(VOS_TRACE_LEVEL_ERROR,
7052 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 __func__, frag_threshold);
7054 return -EIO;
7055 }
7056
7057 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7058 frag_threshold);
7059 }
7060
7061 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7062 || (changed & WIPHY_PARAM_RETRY_LONG))
7063 {
7064 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7065 wiphy->retry_short :
7066 wiphy->retry_long;
7067
7068 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7069 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 __func__, retry_value);
7073 return -EINVAL;
7074 }
7075
7076 if (changed & WIPHY_PARAM_RETRY_SHORT)
7077 {
7078 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7079 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307080 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307082 hddLog(VOS_TRACE_LEVEL_ERROR,
7083 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 __func__, retry_value);
7085 return -EIO;
7086 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 __func__, retry_value);
7089 }
7090 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7091 {
7092 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7093 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307094 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307096 hddLog(VOS_TRACE_LEVEL_ERROR,
7097 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 __func__, retry_value);
7099 return -EIO;
7100 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307101 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007102 __func__, retry_value);
7103 }
7104 }
7105
7106 return 0;
7107}
7108
7109/*
7110 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7111 * This function is used to set the txpower
7112 */
7113static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007114#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7115 struct wireless_dev *wdev,
7116#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007117#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307118 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007119#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307120 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007121#endif
7122 int dbm)
7123{
7124 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307125 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7127 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307128 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007129
7130 ENTER();
7131
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307132 status = wlan_hdd_validate_context(pHddCtx);
7133
7134 if (0 != status)
7135 {
7136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7137 "%s: HDD context is not valid", __func__);
7138 return status;
7139 }
7140
7141 hHal = pHddCtx->hHal;
7142
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307143 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7144 dbm, ccmCfgSetCallback,
7145 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307147 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7149 return -EIO;
7150 }
7151
7152 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7153 dbm);
7154
7155 switch(type)
7156 {
7157 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7158 /* Fall through */
7159 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7160 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7163 __func__);
7164 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 }
7166 break;
7167 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 __func__);
7170 return -EOPNOTSUPP;
7171 break;
7172 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7174 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 return -EIO;
7176 }
7177
7178 return 0;
7179}
7180
7181/*
7182 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7183 * This function is used to read the txpower
7184 */
Yue Maf49ba872013-08-19 12:04:25 -07007185static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7186#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7187 struct wireless_dev *wdev,
7188#endif
7189 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007190{
7191
7192 hdd_adapter_t *pAdapter;
7193 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307194 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007195
Jeff Johnsone7245742012-09-05 17:12:55 -07007196 ENTER();
7197
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307198 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007199
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307200 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007201 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7203 "%s: HDD context is not valid", __func__);
7204 *dbm = 0;
7205 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007206 }
7207
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7209 if (NULL == pAdapter)
7210 {
7211 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7212 return -ENOENT;
7213 }
7214
7215 wlan_hdd_get_classAstats(pAdapter);
7216 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7217
Jeff Johnsone7245742012-09-05 17:12:55 -07007218 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 return 0;
7220}
7221
7222static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7223 u8* mac, struct station_info *sinfo)
7224{
7225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7226 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7227 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7228 tANI_U8 rate_flags;
7229
7230 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7231 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007232
7233 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7234 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7235 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7236 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7237 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7238 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7239 tANI_U16 maxRate = 0;
7240 tANI_U16 myRate;
7241 tANI_U16 currentRate = 0;
7242 tANI_U8 maxSpeedMCS = 0;
7243 tANI_U8 maxMCSIdx = 0;
7244 tANI_U8 rateFlag = 1;
7245 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007246 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307247 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007248
Leo Chang6f8870f2013-03-26 18:11:36 -07007249#ifdef WLAN_FEATURE_11AC
7250 tANI_U32 vht_mcs_map;
7251 eDataRate11ACMaxMcs vhtMaxMcs;
7252#endif /* WLAN_FEATURE_11AC */
7253
Jeff Johnsone7245742012-09-05 17:12:55 -07007254 ENTER();
7255
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7257 (0 == ssidlen))
7258 {
7259 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7260 " Invalid ssidlen, %d", __func__, ssidlen);
7261 /*To keep GUI happy*/
7262 return 0;
7263 }
7264
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307265 status = wlan_hdd_validate_context(pHddCtx);
7266
7267 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007268 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7270 "%s: HDD context is not valid", __func__);
7271 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007272 }
7273
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007274 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7276
Kiet Lam3b17fc82013-09-27 05:24:08 +05307277 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7278 sinfo->filled |= STATION_INFO_SIGNAL;
7279
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 //convert to the UI units of 100kbps
7281 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7282
7283#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007284 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 -07007285 sinfo->signal,
7286 pCfg->reportMaxLinkSpeed,
7287 myRate,
7288 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007289 (int) pCfg->linkSpeedRssiMid,
7290 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007291 (int) rate_flags,
7292 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007293#endif //LINKSPEED_DEBUG_ENABLED
7294
7295 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7296 {
7297 // we do not want to necessarily report the current speed
7298 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7299 {
7300 // report the max possible speed
7301 rssidx = 0;
7302 }
7303 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7304 {
7305 // report the max possible speed with RSSI scaling
7306 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7307 {
7308 // report the max possible speed
7309 rssidx = 0;
7310 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007311 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 {
7313 // report middle speed
7314 rssidx = 1;
7315 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007316 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7317 {
7318 // report middle speed
7319 rssidx = 2;
7320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 else
7322 {
7323 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007324 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 }
7326 }
7327 else
7328 {
7329 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7330 hddLog(VOS_TRACE_LEVEL_ERROR,
7331 "%s: Invalid value for reportMaxLinkSpeed: %u",
7332 __func__, pCfg->reportMaxLinkSpeed);
7333 rssidx = 0;
7334 }
7335
7336 maxRate = 0;
7337
7338 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307339 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7340 OperationalRates, &ORLeng))
7341 {
7342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7343 /*To keep GUI happy*/
7344 return 0;
7345 }
7346
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 for (i = 0; i < ORLeng; i++)
7348 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007349 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 {
7351 /* Validate Rate Set */
7352 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7353 {
7354 currentRate = supported_data_rate[j].supported_rate[rssidx];
7355 break;
7356 }
7357 }
7358 /* Update MAX rate */
7359 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7360 }
7361
7362 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307363 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7364 ExtendedRates, &ERLeng))
7365 {
7366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7367 /*To keep GUI happy*/
7368 return 0;
7369 }
7370
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 for (i = 0; i < ERLeng; i++)
7372 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007373 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 {
7375 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7376 {
7377 currentRate = supported_data_rate[j].supported_rate[rssidx];
7378 break;
7379 }
7380 }
7381 /* Update MAX rate */
7382 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7383 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307384 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307385 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307386 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307387 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307388 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007389 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307390 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7391 MCSRates, &MCSLeng))
7392 {
7393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7394 /*To keep GUI happy*/
7395 return 0;
7396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007398#ifdef WLAN_FEATURE_11AC
7399 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307400 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007401 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007402 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307403 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007404 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007405 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007406 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007408 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007410 maxMCSIdx = 7;
7411 }
7412 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7413 {
7414 maxMCSIdx = 8;
7415 }
7416 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7417 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307418 //VHT20 is supporting 0~8
7419 if (rate_flags & eHAL_TX_RATE_VHT20)
7420 maxMCSIdx = 8;
7421 else
7422 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007423 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307424
7425 if (rate_flags & eHAL_TX_RATE_VHT80)
7426 {
7427 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7428 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7429 }
7430 else if (rate_flags & eHAL_TX_RATE_VHT40)
7431 {
7432 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7433 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7434 }
7435 else if (rate_flags & eHAL_TX_RATE_VHT20)
7436 {
7437 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7438 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7439 }
7440
Leo Chang6f8870f2013-03-26 18:11:36 -07007441 maxSpeedMCS = 1;
7442 if (currentRate > maxRate)
7443 {
7444 maxRate = currentRate;
7445 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307446
Leo Chang6f8870f2013-03-26 18:11:36 -07007447 }
7448 else
7449#endif /* WLAN_FEATURE_11AC */
7450 {
7451 if (rate_flags & eHAL_TX_RATE_HT40)
7452 {
7453 rateFlag |= 1;
7454 }
7455 if (rate_flags & eHAL_TX_RATE_SGI)
7456 {
7457 rateFlag |= 2;
7458 }
7459
7460 for (i = 0; i < MCSLeng; i++)
7461 {
7462 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7463 for (j = 0; j < temp; j++)
7464 {
7465 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7466 {
7467 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7468 break;
7469 }
7470 }
7471 if ((j < temp) && (currentRate > maxRate))
7472 {
7473 maxRate = currentRate;
7474 maxSpeedMCS = 1;
7475 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 }
7478 }
7479 }
7480
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307481 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7482 {
7483 maxRate = myRate;
7484 maxSpeedMCS = 1;
7485 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7486 }
7487
Jeff Johnson295189b2012-06-20 16:38:30 -07007488 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007489 if (((maxRate < myRate) && (0 == rssidx)) ||
7490 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 {
7492 maxRate = myRate;
7493 if (rate_flags & eHAL_TX_RATE_LEGACY)
7494 {
7495 maxSpeedMCS = 0;
7496 }
7497 else
7498 {
7499 maxSpeedMCS = 1;
7500 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7501 }
7502 }
7503
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307504 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 {
7506 sinfo->txrate.legacy = maxRate;
7507#ifdef LINKSPEED_DEBUG_ENABLED
7508 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7509#endif //LINKSPEED_DEBUG_ENABLED
7510 }
7511 else
7512 {
7513 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007514#ifdef WLAN_FEATURE_11AC
7515 sinfo->txrate.nss = 1;
7516 if (rate_flags & eHAL_TX_RATE_VHT80)
7517 {
7518 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307519 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007520 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307521 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007522 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307523 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7524 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7525 }
7526 else if (rate_flags & eHAL_TX_RATE_VHT20)
7527 {
7528 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7529 }
7530#endif /* WLAN_FEATURE_11AC */
7531 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7532 {
7533 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7534 if (rate_flags & eHAL_TX_RATE_HT40)
7535 {
7536 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7537 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007539 if (rate_flags & eHAL_TX_RATE_SGI)
7540 {
7541 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7542 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307543
Jeff Johnson295189b2012-06-20 16:38:30 -07007544#ifdef LINKSPEED_DEBUG_ENABLED
7545 pr_info("Reporting MCS rate %d flags %x\n",
7546 sinfo->txrate.mcs,
7547 sinfo->txrate.flags );
7548#endif //LINKSPEED_DEBUG_ENABLED
7549 }
7550 }
7551 else
7552 {
7553 // report current rate instead of max rate
7554
7555 if (rate_flags & eHAL_TX_RATE_LEGACY)
7556 {
7557 //provide to the UI in units of 100kbps
7558 sinfo->txrate.legacy = myRate;
7559#ifdef LINKSPEED_DEBUG_ENABLED
7560 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7561#endif //LINKSPEED_DEBUG_ENABLED
7562 }
7563 else
7564 {
7565 //must be MCS
7566 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007567#ifdef WLAN_FEATURE_11AC
7568 sinfo->txrate.nss = 1;
7569 if (rate_flags & eHAL_TX_RATE_VHT80)
7570 {
7571 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7572 }
7573 else
7574#endif /* WLAN_FEATURE_11AC */
7575 {
7576 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007578 if (rate_flags & eHAL_TX_RATE_SGI)
7579 {
7580 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7581 }
7582 if (rate_flags & eHAL_TX_RATE_HT40)
7583 {
7584 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7585 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007586#ifdef WLAN_FEATURE_11AC
7587 else if (rate_flags & eHAL_TX_RATE_VHT80)
7588 {
7589 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7590 }
7591#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007592#ifdef LINKSPEED_DEBUG_ENABLED
7593 pr_info("Reporting actual MCS rate %d flags %x\n",
7594 sinfo->txrate.mcs,
7595 sinfo->txrate.flags );
7596#endif //LINKSPEED_DEBUG_ENABLED
7597 }
7598 }
7599 sinfo->filled |= STATION_INFO_TX_BITRATE;
7600
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007601 sinfo->tx_packets =
7602 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7603 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7604 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7605 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7606
7607 sinfo->tx_retries =
7608 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7609 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7610 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7611 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7612
7613 sinfo->tx_failed =
7614 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7615 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7616 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7617 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7618
7619 sinfo->filled |=
7620 STATION_INFO_TX_PACKETS |
7621 STATION_INFO_TX_RETRIES |
7622 STATION_INFO_TX_FAILED;
7623
7624 EXIT();
7625 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007626}
7627
7628static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007629 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007630{
7631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307632 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307634 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007635
Jeff Johnsone7245742012-09-05 17:12:55 -07007636 ENTER();
7637
Jeff Johnson295189b2012-06-20 16:38:30 -07007638 if (NULL == pAdapter)
7639 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 return -ENODEV;
7642 }
7643
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307645 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307646
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307647 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307648 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7650 "%s: HDD context is not valid", __func__);
7651 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307652 }
7653
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307654 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7655 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7656 (pHddCtx->cfg_ini->fhostArpOffload) &&
7657 (eConnectionState_Associated ==
7658 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7659 {
Amar Singhald53568e2013-09-26 11:03:45 -07007660
7661 hddLog(VOS_TRACE_LEVEL_INFO,
7662 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307663 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307664 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7665 {
7666 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007667 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307668 __func__, vos_status);
7669 }
7670 }
7671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 /**The get power cmd from the supplicant gets updated by the nl only
7673 *on successful execution of the function call
7674 *we are oppositely mapped w.r.t mode in the driver
7675 **/
7676 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7677
Jeff Johnsone7245742012-09-05 17:12:55 -07007678 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007679 if (VOS_STATUS_E_FAILURE == vos_status)
7680 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7682 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 return -EINVAL;
7684 }
7685 return 0;
7686}
7687
7688
7689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7690static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7691 struct net_device *netdev,
7692 u8 key_index)
7693{
Jeff Johnsone7245742012-09-05 17:12:55 -07007694 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 return 0;
7696}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307697#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007698
7699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7700static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7701 struct net_device *dev,
7702 struct ieee80211_txq_params *params)
7703{
Jeff Johnsone7245742012-09-05 17:12:55 -07007704 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 return 0;
7706}
7707#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7708static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7709 struct ieee80211_txq_params *params)
7710{
Jeff Johnsone7245742012-09-05 17:12:55 -07007711 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 return 0;
7713}
7714#endif //LINUX_VERSION_CODE
7715
7716static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7717 struct net_device *dev, u8 *mac)
7718{
7719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307720 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007721 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307722 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007723 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007724
Jeff Johnsone7245742012-09-05 17:12:55 -07007725 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307726 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 return -EINVAL;
7730 }
7731
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7733 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007734
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307735 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7738 "%s: HDD context is not valid", __func__);
7739 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007740 }
7741
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 )
7745 {
7746 if( NULL == mac )
7747 {
7748 v_U16_t i;
7749 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7750 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007751 if ((pAdapter->aStaInfo[i].isUsed) &&
7752 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007753 {
7754 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7755 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007756 "%s: Delete STA with MAC::"
7757 MAC_ADDRESS_STR,
7758 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007759 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7760 if (VOS_IS_STATUS_SUCCESS(vos_status))
7761 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 }
7763 }
7764 }
7765 else
7766 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007767
7768 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7769 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7770 {
7771 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007772 "%s: Skip this DEL STA as this is not used::"
7773 MAC_ADDRESS_STR,
7774 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007775 return -ENOENT;
7776 }
7777
7778 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7779 {
7780 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007781 "%s: Skip this DEL STA as deauth is in progress::"
7782 MAC_ADDRESS_STR,
7783 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007784 return -ENOENT;
7785 }
7786
7787 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7788
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 hddLog(VOS_TRACE_LEVEL_INFO,
7790 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007791 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007793 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007794
7795 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7796 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7797 {
7798 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7799 hddLog(VOS_TRACE_LEVEL_INFO,
7800 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007801 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007802 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007803 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007804 return -ENOENT;
7805 }
7806
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 }
7808 }
7809
7810 EXIT();
7811
7812 return 0;
7813}
7814
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007815static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7816 struct net_device *dev, u8 *mac, struct station_parameters *params)
7817{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007818 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007819#ifdef FEATURE_WLAN_TDLS
7820 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007821 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007822 mask = params->sta_flags_mask;
7823
7824 set = params->sta_flags_set;
7825
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007826#ifdef WLAN_FEATURE_TDLS_DEBUG
7827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7828 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7829 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7830#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007831
7832 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7833 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007834 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007835 }
7836 }
7837#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007838 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007839}
7840
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007841
7842#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007843#define MAX_PMKSAIDS_IN_CACHE 8
7844
7845static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7846static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7847
7848
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007849static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007850 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307852 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007853 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7854 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307855 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307856 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007857 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307858 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307859
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007860 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
7861 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07007862
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307863 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307864 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007867 return -EINVAL;
7868 }
7869
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307870 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7871 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007872
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307873 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007874 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7876 "%s: HDD context is not valid", __func__);
7877 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007878 }
7879
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307880 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007881 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7882
Wilson Yang6507c4e2013-10-01 20:11:19 -07007883 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307885 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886 pmksa->bssid, WNI_CFG_BSSID_LEN))
7887 {
7888 /* BSSID matched previous entry. Overwrite it. */
7889 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307890 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007891 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307892 vos_mem_copy(PMKIDCache[j].PMKID,
7893 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007894 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007896 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007897 dump_bssid(pmksa->bssid);
7898 dump_pmkid(halHandle, pmksa->pmkid);
7899 break;
7900 }
7901 }
7902
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007903 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07007904 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007905
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007906 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307907 {
7908 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07007909 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307910 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007911 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307912 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007913 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307914 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007915 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007916 dump_bssid(pmksa->bssid);
7917 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307918 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007919 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07007920 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007921 }
7922
7923
7924 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307925 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007926 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307927 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007928 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007929 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307930 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7931 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007932 PMKIDCacheIndex);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007933 return 0;
7934}
7935
7936
Wilson Yang6507c4e2013-10-01 20:11:19 -07007937
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007938static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007939 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007940{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007941 tANI_U32 j=0;
7942 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7943 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007944 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007945 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08007946 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007947
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007948 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
7949 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007950
7951 /* Validate pAdapter */
7952 if (NULL == pAdapter)
7953 {
7954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
7955 return -EINVAL;
7956 }
7957
7958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7959 status = wlan_hdd_validate_context(pHddCtx);
7960
7961 if (0 != status)
7962 {
7963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7964 "%s: HDD context is not valid", __func__);
7965 return status;
7966 }
7967
7968 /*Retrieve halHandle*/
7969 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7970
7971 /*in case index is 0,no entry to delete*/
7972 if (0 == PMKIDCacheIndex)
7973 {
7974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7975 __func__);
7976 return -EINVAL;
7977 }
7978
7979 /*find the matching PMKSA entry from j=0 to (index-1),
7980 * and delete the matched one
7981 */
7982 for (j = 0; j<PMKIDCacheIndex; j++)
7983 {
7984 if (vos_mem_compare(PMKIDCache[j].BSSID,
7985 pmksa->bssid,
7986 WNI_CFG_BSSID_LEN))
7987 {
7988 /* BSSID matched entry */
7989 BSSIDMatched = 1;
7990
7991 if (j<PMKIDCacheIndex-1)
7992 {
7993 /*replace the matching entry with the last entry in HDD local cache*/
7994 vos_mem_copy(PMKIDCache[j].BSSID,
7995 PMKIDCache[PMKIDCacheIndex-1].BSSID,
7996 WNI_CFG_BSSID_LEN);
7997 vos_mem_copy(PMKIDCache[j].PMKID,
7998 PMKIDCache[PMKIDCacheIndex-1].PMKID,
7999 CSR_RSN_PMKID_SIZE);
8000 }
8001
8002 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008003 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8004 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8005
8006 /*reduce the PMKID array index*/
8007 PMKIDCacheIndex--;
8008
8009 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008010 if (eHAL_STATUS_SUCCESS !=
8011 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008012 {
8013 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8014 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008015 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008016 }
8017
8018 dump_bssid(pmksa->bssid);
8019 dump_pmkid(halHandle,pmksa->pmkid);
8020
8021 break;
8022 }
8023 }
8024
8025 /* we compare all entries,but cannot find matching entry */
8026 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8027 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008028 hddLog(VOS_TRACE_LEVEL_FATAL,
8029 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8030 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008031 dump_bssid(pmksa->bssid);
8032 dump_pmkid(halHandle, pmksa->pmkid);
8033 return -EINVAL;
8034 }
Wilson Yangef657d32014-01-15 19:19:23 -08008035 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008036}
8037
Wilson Yang6507c4e2013-10-01 20:11:19 -07008038
8039
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008040static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8041{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008042 tANI_U32 j=0;
8043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8044 tHalHandle halHandle;
8045 hdd_context_t *pHddCtx;
8046 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008047 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008048
8049 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8050
8051 /* Validate pAdapter */
8052 if (NULL == pAdapter)
8053 {
8054 hddLog(VOS_TRACE_LEVEL_ERROR,
8055 "%s: Invalid Adapter" ,__func__);
8056 return -EINVAL;
8057 }
8058
8059 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8060 status = wlan_hdd_validate_context(pHddCtx);
8061
8062 if (0 != status)
8063 {
8064 hddLog(VOS_TRACE_LEVEL_ERROR,
8065 "%s: HDD context is not valid", __func__);
8066 return status;
8067 }
8068
8069 /*Retrieve halHandle*/
8070 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8071
8072 /*in case index is 0,no entry to delete*/
8073 if (0 == PMKIDCacheIndex)
8074 {
8075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8076 __func__);
8077 return -EINVAL;
8078 }
8079
8080 /*delete all the PMKSA one by one */
8081 for (j = 0; j<PMKIDCacheIndex; j++)
8082 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008083 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008084
8085 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008086 if (eHAL_STATUS_SUCCESS !=
8087 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008088 {
8089 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8090 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008091 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008092 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308093 /*clear the entry in HDD cache 0--index-1 */
8094 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8095 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008096 }
8097
8098 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008099 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008100}
8101#endif
8102
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008103#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308104static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008105 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8106{
8107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8108 hdd_station_ctx_t *pHddStaCtx;
8109
8110 if (NULL == pAdapter)
8111 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008113 return -ENODEV;
8114 }
8115
8116 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8117
8118 // Added for debug on reception of Re-assoc Req.
8119 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8120 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008121 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008122 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008123 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008124 }
8125
8126#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008127 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008128 ftie->ie_len);
8129#endif
8130
8131 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308132 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8133 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008134 ftie->ie_len);
8135 return 0;
8136}
8137#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008138
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308139#ifdef FEATURE_WLAN_SCAN_PNO
8140
8141void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8142 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8143{
8144 int ret;
8145 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8146 hdd_context_t *pHddCtx;
8147
Nirav Shah80830bf2013-12-31 16:35:12 +05308148 ENTER();
8149
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308150 if (NULL == pAdapter)
8151 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308153 "%s: HDD adapter is Null", __func__);
8154 return ;
8155 }
8156
8157 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8158 if (NULL == pHddCtx)
8159 {
8160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8161 "%s: HDD context is Null!!!", __func__);
8162 return ;
8163 }
8164
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308165 spin_lock(&pHddCtx->schedScan_lock);
8166 if (TRUE == pHddCtx->isWiphySuspended)
8167 {
8168 pHddCtx->isSchedScanUpdatePending = TRUE;
8169 spin_unlock(&pHddCtx->schedScan_lock);
8170 hddLog(VOS_TRACE_LEVEL_INFO,
8171 "%s: Update cfg80211 scan database after it resume", __func__);
8172 return ;
8173 }
8174 spin_unlock(&pHddCtx->schedScan_lock);
8175
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308176 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8177
8178 if (0 > ret)
8179 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8180
8181 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8183 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308184}
8185
8186/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308187 * FUNCTION: wlan_hdd_is_pno_allowed
8188 * To check is there any P2P GO/SAP or P2P Client/STA
8189 * session is active
8190 */
8191static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8192{
8193 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8194 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308195 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308196 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8197 int status = 0;
8198 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8199
8200 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8201 {
8202 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308203 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308204
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308205 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8206 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8207 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8208 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8209 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8210 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308211 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308212 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308213 }
8214 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8215 pAdapterNode = pNext;
8216 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308217 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308218}
8219
8220/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308221 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8222 * NL interface to enable PNO
8223 */
8224static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8225 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8226{
8227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8228 tpSirPNOScanReq pPnoRequest = NULL;
8229 hdd_context_t *pHddCtx;
8230 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308231 v_U32_t i, indx, num_ch, tempInterval;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308232 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8233 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8234 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8235 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308236 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308237
8238 if (NULL == pAdapter)
8239 {
8240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8241 "%s: HDD adapter is Null", __func__);
8242 return -ENODEV;
8243 }
8244
8245 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308246 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308247
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308248 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308249 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8251 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308252 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308253 }
8254
8255 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8256 if (NULL == hHal)
8257 {
8258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8259 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308260 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308261 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308262
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308263 /* The current firmware design for PNO does not consider concurrent
8264 * active sessions.Hence , determine the concurrent active sessions
8265 * and return a failure to the framework on a request for schedule
8266 * scan.
8267 */
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308268 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308269 {
8270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308271 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308272 return -EBUSY;
8273 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308274
8275 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8276 if (NULL == pPnoRequest)
8277 {
8278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8279 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308280 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308281 }
8282
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308283 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308284 pPnoRequest->enable = 1; /*Enable PNO */
8285 pPnoRequest->ucNetworksCount = request->n_match_sets;
8286
8287 if (( !pPnoRequest->ucNetworksCount ) ||
8288 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8289 {
8290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308291 "%s: Network input is not correct %d",
8292 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308293 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308294 goto error;
8295 }
8296
8297 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8298 {
8299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308300 "%s: Incorrect number of channels %d",
8301 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308302 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308303 goto error;
8304 }
8305
8306 /* Framework provides one set of channels(all)
8307 * common for all saved profile */
8308 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8309 channels_allowed, &num_channels_allowed))
8310 {
8311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8312 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308313 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308314 goto error;
8315 }
8316 /* Checking each channel against allowed channel list */
8317 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308318 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308319 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308320 char chList [(request->n_channels*5)+1];
8321 int len;
8322 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308323 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308324 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308325 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308326 if (request->channels[i]->hw_value == channels_allowed[indx])
8327 {
8328 valid_ch[num_ch++] = request->channels[i]->hw_value;
8329 len += snprintf(chList+len, 5, "%d ",
8330 request->channels[i]->hw_value);
8331 break ;
8332 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308333 }
8334 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308335 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8336 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308337
8338 /* Filling per profile params */
8339 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8340 {
8341 pPnoRequest->aNetworks[i].ssId.length =
8342 request->match_sets[i].ssid.ssid_len;
8343
8344 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8345 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8346 {
8347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308348 "%s: SSID Len %d is not correct for network %d",
8349 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308350 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308351 goto error;
8352 }
8353
8354 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8355 request->match_sets[i].ssid.ssid,
8356 request->match_sets[i].ssid.ssid_len);
8357 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8358 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8359 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8360
8361 /*Copying list of valid channel into request */
8362 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8363 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8364
8365 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8366 }
8367
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008369 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308370 if ((0 < request->ie_len) && (NULL != request->ie))
8371 {
8372 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8373 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8374 pPnoRequest->us24GProbeTemplateLen);
8375
8376 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8377 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8378 pPnoRequest->us5GProbeTemplateLen);
8379 }
8380
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308381 /* Driver gets only one time interval which is hardcoded in
8382 * supplicant for 10000ms. Taking power consumption into account 6 timers
8383 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8384 * 80,160,320 secs. And number of scan cycle for each timer
8385 * is configurable through INI param gPNOScanTimerRepeatValue.
8386 * If it is set to 0 only one timer will be used and PNO scan cycle
8387 * will be repeated after each interval specified by supplicant
8388 * till PNO is disabled.
8389 */
8390 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8391 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8392 else
8393 pPnoRequest->scanTimers.ucScanTimersCount =
8394 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8395
8396 tempInterval = (request->interval)/1000;
8397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8398 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8399 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8400 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8401 {
8402 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8403 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8404 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8405 tempInterval *= 2;
8406 }
8407 //Repeat last timer until pno disabled.
8408 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8409
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308410 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308411
Nirav Shah80830bf2013-12-31 16:35:12 +05308412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8413 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8414 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8415 pPnoRequest->scanTimers.ucScanTimersCount);
8416
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308417 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8418 pPnoRequest, pAdapter->sessionId,
8419 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8420 if (eHAL_STATUS_SUCCESS != status)
8421 {
8422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308423 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308424 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308425 goto error;
8426 }
8427
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8429 "PNO scanRequest offloaded");
8430
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308431error:
8432 vos_mem_free(pPnoRequest);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308433 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308434}
8435
8436/*
8437 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8438 * NL interface to disable PNO
8439 */
8440static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8441 struct net_device *dev)
8442{
8443 eHalStatus status = eHAL_STATUS_FAILURE;
8444 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8445 hdd_context_t *pHddCtx;
8446 tHalHandle hHal;
8447 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308448 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308449
8450 ENTER();
8451
8452 if (NULL == pAdapter)
8453 {
8454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8455 "%s: HDD adapter is Null", __func__);
8456 return -ENODEV;
8457 }
8458
8459 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308460
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308461 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308462 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308464 "%s: HDD context is Null", __func__);
8465 return -ENODEV;
8466 }
8467
8468 /* The return 0 is intentional when isLogpInProgress and
8469 * isLoadUnloadInProgress. We did observe a crash due to a return of
8470 * failure in sched_scan_stop , especially for a case where the unload
8471 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8472 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8473 * success. If it returns a failure , then its next invocation due to the
8474 * clean up of the second interface will have the dev pointer corresponding
8475 * to the first one leading to a crash.
8476 */
8477 if (pHddCtx->isLogpInProgress)
8478 {
8479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8480 "%s: LOGP in Progress. Ignore!!!", __func__);
8481 return ret;
8482 }
8483
8484 if (pHddCtx->isLoadUnloadInProgress)
8485 {
8486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8487 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8488 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308489 }
8490
8491 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8492 if (NULL == hHal)
8493 {
8494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8495 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308496 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308497 }
8498
8499 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8500 if (NULL == pPnoRequest)
8501 {
8502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8503 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308504 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308505 }
8506
8507 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8508 pPnoRequest->enable = 0; /* Disable PNO */
8509 pPnoRequest->ucNetworksCount = 0;
8510
8511 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8512 pAdapter->sessionId,
8513 NULL, pAdapter);
8514 if (eHAL_STATUS_SUCCESS != status)
8515 {
8516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8517 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308518 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308519 }
8520
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8522 "%s: PNO scan disabled", __func__);
8523
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308524 vos_mem_free(pPnoRequest);
8525
8526 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308527 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308528}
8529
8530#endif /*FEATURE_WLAN_SCAN_PNO*/
8531
8532
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008533#ifdef FEATURE_WLAN_TDLS
8534static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8535 u8 *peer, u8 action_code, u8 dialog_token,
8536 u16 status_code, const u8 *buf, size_t len)
8537{
8538
8539 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8540 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008541 u8 peerMac[6];
8542 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008543 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008544 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008545 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008546
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008547 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008548 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008550 "Invalid arguments");
8551 return -EINVAL;
8552 }
8553
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008554 if (pHddCtx->isLogpInProgress)
8555 {
8556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8557 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008558 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008559 return -EBUSY;
8560 }
8561
Hoonki Lee27511902013-03-14 18:19:06 -07008562 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008563 {
Hoonki Lee27511902013-03-14 18:19:06 -07008564 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8565 "%s: TDLS mode is disabled OR not enabled in FW."
8566 MAC_ADDRESS_STR " action %d declined.",
8567 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008568 return -ENOTSUPP;
8569 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008570
Hoonki Lee27511902013-03-14 18:19:06 -07008571 /* other than teardown frame, other mgmt frames are not sent if disabled */
8572 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8573 {
8574 /* if tdls_mode is disabled to respond to peer's request */
8575 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8576 {
8577 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8578 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008579 " TDLS mode is disabled. action %d declined.",
8580 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008581
8582 return -ENOTSUPP;
8583 }
8584 }
8585
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008586 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8587 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308588 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008589 {
8590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008591 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008592 " TDLS setup is ongoing. action %d declined.",
8593 __func__, MAC_ADDR_ARRAY(peer), action_code);
8594 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008595 }
8596 }
8597
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008598 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8599 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008600 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008601 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008602 {
8603 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8604 we return error code at 'add_station()'. Hence we have this
8605 check again in addtion to add_station().
8606 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008607 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008608 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8610 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008611 " TDLS Max peer already connected. action %d declined.",
8612 __func__, MAC_ADDR_ARRAY(peer), action_code);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308613 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008614 }
8615 else
8616 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008617 /* maximum reached. tweak to send error code to peer and return
8618 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008619 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8621 "%s: " MAC_ADDRESS_STR
8622 " TDLS Max peer already connected send response status %d",
8623 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008624 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008625 /* fall through to send setup resp with failure status
8626 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008627 }
8628 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008629 else
8630 {
8631 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308632 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008633 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008634 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008636 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8637 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008638 return -EPERM;
8639 }
8640 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008641 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008642 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008643
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008644#ifdef WLAN_FEATURE_TDLS_DEBUG
8645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008646 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
8647 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8648 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008649#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008650
Hoonki Leea34dd892013-02-05 22:56:02 -08008651 /*Except teardown responder will not be used so just make 0*/
8652 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008653 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008654 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008655
8656 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308657 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008658
8659 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8660 responder = pTdlsPeer->is_responder;
8661 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008662 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8664 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
8665 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8666 dialog_token, status_code, len);
8667 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008668 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008669 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008670
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308671 /* For explicit trigger of DIS_REQ come out of BMPS for
8672 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008673 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308674 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8675 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008676 {
8677 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8678 {
8679 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308680 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008681 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8682 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308683 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8684 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008685 }
8686
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008687 /* make sure doesn't call send_mgmt() while it is pending */
8688 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8689 {
8690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008691 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008692 __func__, MAC_ADDR_ARRAY(peer), action_code);
8693 return -EBUSY;
8694 }
8695
8696 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008697 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8698
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008699 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08008700 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008701
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008702 if (VOS_STATUS_SUCCESS != status)
8703 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8705 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008706 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008707 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308708 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008709 }
8710
Hoonki Leed37cbb32013-04-20 00:31:14 -07008711 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8712 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8713
8714 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008715 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008717 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008718 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008719 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008720
8721 if (pHddCtx->isLogpInProgress)
8722 {
8723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8724 "%s: LOGP in Progress. Ignore!!!", __func__);
8725 return -EAGAIN;
8726 }
8727
Hoonki Leed37cbb32013-04-20 00:31:14 -07008728 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308729 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008730 }
8731
Gopichand Nakkala05922802013-03-14 12:23:19 -07008732 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008733 {
8734 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008735 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008736 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008737
Hoonki Leea34dd892013-02-05 22:56:02 -08008738 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8739 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008740 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008741 }
8742 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8743 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008744 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008745 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008746
8747 return 0;
8748}
8749
8750static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8751 u8 *peer, enum nl80211_tdls_operation oper)
8752{
8753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8754 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308755 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008756 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008757
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308758 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008759 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008761 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008762 return -EINVAL;
8763 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008764
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308765 status = wlan_hdd_validate_context(pHddCtx);
8766
8767 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008768 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8770 "%s: HDD context is not valid", __func__);
8771 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008772 }
8773
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008774
8775 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008776 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008777 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008779 "TDLS Disabled in INI OR not enabled in FW. "
8780 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008781 return -ENOTSUPP;
8782 }
8783
8784 switch (oper) {
8785 case NL80211_TDLS_ENABLE_LINK:
8786 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008787 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308788 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308789 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008790
Sunil Dutt41de4e22013-11-14 18:09:02 +05308791 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8792
8793 if ( NULL == pTdlsPeer ) {
8794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8795 " (oper %d) not exsting. ignored",
8796 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8797 return -EINVAL;
8798 }
8799
8800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8801 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8802 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8803 "NL80211_TDLS_ENABLE_LINK");
8804
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07008805 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
8806 {
8807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
8808 MAC_ADDRESS_STR " failed",
8809 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
8810 return -EINVAL;
8811 }
8812
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008813 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008814 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308815 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05308816
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308817 if (0 != wlan_hdd_tdls_get_link_establish_params(
8818 pAdapter, peer,&tdlsLinkEstablishParams)) {
8819 return -EINVAL;
8820 }
8821 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308822
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308823 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
8824 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
8825 /* Send TDLS peer UAPSD capabilities to the firmware and
8826 * register with the TL on after the response for this operation
8827 * is received .
8828 */
8829 ret = wait_for_completion_interruptible_timeout(
8830 &pAdapter->tdls_link_establish_req_comp,
8831 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
8832 if (ret <= 0)
8833 {
8834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8835 "%s: Link Establish Request Faled Status %ld",
8836 __func__, ret);
8837 return -EINVAL;
8838 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308839 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008840 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05308841 /* Mark TDLS client Authenticated .*/
8842 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
8843 pTdlsPeer->staId,
8844 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008845 if (VOS_STATUS_SUCCESS == status)
8846 {
Hoonki Lee14621352013-04-16 17:51:19 -07008847 if (pTdlsPeer->is_responder == 0)
8848 {
8849 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
8850
8851 wlan_hdd_tdls_timer_restart(pAdapter,
8852 &pTdlsPeer->initiatorWaitTimeoutTimer,
8853 WAIT_TIME_TDLS_INITIATOR);
8854 /* suspend initiator TX until it receives direct packet from the
8855 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
8856 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8857 &staId, NULL);
8858 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008859 wlan_hdd_tdls_increment_peer_count(pAdapter);
8860 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008861 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308862
8863 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308864 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
8865 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308866 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308867 int ac;
8868 uint8 ucAc[4] = { WLANTL_AC_VO,
8869 WLANTL_AC_VI,
8870 WLANTL_AC_BK,
8871 WLANTL_AC_BE };
8872 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
8873 for(ac=0; ac < 4; ac++)
8874 {
8875 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8876 pTdlsPeer->staId, ucAc[ac],
8877 tlTid[ac], tlTid[ac], 0, 0,
8878 WLANTL_BI_DIR );
8879 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308880 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008881 }
8882
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008883 }
8884 break;
8885 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08008886 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05308887 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8888
8889 if ( NULL == pTdlsPeer ) {
8890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8891 " (oper %d) not exsting. ignored",
8892 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8893 return -EINVAL;
8894 }
8895
8896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8897 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8898 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8899 "NL80211_TDLS_DISABLE_LINK");
8900
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008901 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008902 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008903 long status;
8904
8905 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
8906
Lee Hoonkic1262f22013-01-24 21:59:00 -08008907 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
8908 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008909
8910 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
8911 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
8912 if (status <= 0)
8913 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008914 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8916 "%s: Del station failed status %ld",
8917 __func__, status);
8918 return -EPERM;
8919 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008920 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008921 }
8922 else
8923 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8925 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008926 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008927 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008928 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008929 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308930 {
8931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8932 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
8933 __func__, MAC_ADDR_ARRAY(peer));
8934
8935 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8936 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8937
8938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8939 " %s TDLS External control and Implicit Trigger not enabled ",
8940 __func__);
8941 return -ENOTSUPP;
8942 }
8943
Sunil Dutt41de4e22013-11-14 18:09:02 +05308944
8945 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8946
8947 if ( NULL == pTdlsPeer ) {
8948 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
8949 " peer not exsting",
8950 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308951 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308952 }
8953 else {
8954 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
8955 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
8956 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308957
8958 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
8959 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308960 break;
8961 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008962 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308963 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308964 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8966 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
8967 __func__, MAC_ADDR_ARRAY(peer));
8968
8969 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8970 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8971
8972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8973 " %s TDLS External control and Implicit Trigger not enabled ",
8974 __func__);
8975 return -ENOTSUPP;
8976 }
8977
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308978 /* To cater the requirement of establishing the TDLS link
8979 * irrespective of the data traffic , get an entry of TDLS peer.
8980 */
8981 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
8982 if (pTdlsPeer == NULL) {
8983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8984 "%s: peer " MAC_ADDRESS_STR " not existing",
8985 __func__, MAC_ADDR_ARRAY(peer));
8986 return -EINVAL;
8987 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308988
8989 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
8990
8991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8992 " %s TDLS Add Force Peer Failed",
8993 __func__);
8994 return -EINVAL;
8995 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308996 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308997 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008998 case NL80211_TDLS_DISCOVERY_REQ:
8999 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9001 "%s: We don't support in-driver setup/teardown/discovery "
9002 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009003 return -ENOTSUPP;
9004 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9006 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009007 return -ENOTSUPP;
9008 }
9009 return 0;
9010}
Chilam NG571c65a2013-01-19 12:27:36 +05309011
9012int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9013 struct net_device *dev, u8 *peer)
9014{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009015 hddLog(VOS_TRACE_LEVEL_INFO,
9016 "tdls send discover req: "MAC_ADDRESS_STR,
9017 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309018
9019 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9020 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
9021}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009022#endif
9023
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309024#ifdef WLAN_FEATURE_GTK_OFFLOAD
9025/*
9026 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9027 * Callback rountine called upon receiving response for
9028 * get offload info
9029 */
9030void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9031 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9032{
9033
9034 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309035 tANI_U8 tempReplayCounter[8];
9036 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309037
9038 ENTER();
9039
9040 if (NULL == pAdapter)
9041 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309043 "%s: HDD adapter is Null", __func__);
9044 return ;
9045 }
9046
9047 if (NULL == pGtkOffloadGetInfoRsp)
9048 {
9049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9050 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9051 return ;
9052 }
9053
9054 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9055 {
9056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9057 "%s: wlan Failed to get replay counter value",
9058 __func__);
9059 return ;
9060 }
9061
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309062 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9063 /* Update replay counter */
9064 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9065 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9066
9067 {
9068 /* changing from little to big endian since supplicant
9069 * works on big endian format
9070 */
9071 int i;
9072 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9073
9074 for (i = 0; i < 8; i++)
9075 {
9076 tempReplayCounter[7-i] = (tANI_U8)p[i];
9077 }
9078 }
9079
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309080 /* Update replay counter to NL */
9081 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309082 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309083}
9084
9085/*
9086 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9087 * This function is used to offload GTK rekeying job to the firmware.
9088 */
9089int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9090 struct cfg80211_gtk_rekey_data *data)
9091{
9092 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9093 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9094 hdd_station_ctx_t *pHddStaCtx;
9095 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309096 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309097 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309098 eHalStatus status = eHAL_STATUS_FAILURE;
9099
9100 ENTER();
9101
9102 if (NULL == pAdapter)
9103 {
9104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9105 "%s: HDD adapter is Null", __func__);
9106 return -ENODEV;
9107 }
9108
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309109 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309110
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309111 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309112 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9114 "%s: HDD context is not valid", __func__);
9115 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309116 }
9117
9118 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9119 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9120 if (NULL == hHal)
9121 {
9122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9123 "%s: HAL context is Null!!!", __func__);
9124 return -EAGAIN;
9125 }
9126
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309127 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9128 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9129 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9130 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309131 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309132 {
9133 /* changing from big to little endian since driver
9134 * works on little endian format
9135 */
9136 tANI_U8 *p =
9137 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9138 int i;
9139
9140 for (i = 0; i < 8; i++)
9141 {
9142 p[7-i] = data->replay_ctr[i];
9143 }
9144 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309145
9146 if (TRUE == pHddCtx->hdd_wlan_suspended)
9147 {
9148 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309149 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9150 sizeof (tSirGtkOffloadParams));
9151 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309152 pAdapter->sessionId);
9153
9154 if (eHAL_STATUS_SUCCESS != status)
9155 {
9156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9157 "%s: sme_SetGTKOffload failed, returned %d",
9158 __func__, status);
9159 return status;
9160 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9162 "%s: sme_SetGTKOffload successfull", __func__);
9163 }
9164 else
9165 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9167 "%s: wlan not suspended GTKOffload request is stored",
9168 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309169 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309170
9171 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309172}
9173#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9174
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309175/*
9176 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9177 * This function is used to set access control policy
9178 */
9179static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9180 struct net_device *dev, const struct cfg80211_acl_data *params)
9181{
9182 int i;
9183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9184 hdd_hostapd_state_t *pHostapdState;
9185 tsap_Config_t *pConfig;
9186 v_CONTEXT_t pVosContext = NULL;
9187 hdd_context_t *pHddCtx;
9188 int status;
9189
9190 ENTER();
9191
9192 if (NULL == pAdapter)
9193 {
9194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9195 "%s: HDD adapter is Null", __func__);
9196 return -ENODEV;
9197 }
9198
9199 if (NULL == params)
9200 {
9201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9202 "%s: params is Null", __func__);
9203 return -EINVAL;
9204 }
9205
9206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9207 status = wlan_hdd_validate_context(pHddCtx);
9208
9209 if (0 != status)
9210 {
9211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9212 "%s: HDD context is not valid", __func__);
9213 return status;
9214 }
9215
9216 pVosContext = pHddCtx->pvosContext;
9217 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9218
9219 if (NULL == pHostapdState)
9220 {
9221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9222 "%s: pHostapdState is Null", __func__);
9223 return -EINVAL;
9224 }
9225
9226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9227 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9228
9229 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9230 {
9231 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9232
9233 /* default value */
9234 pConfig->num_accept_mac = 0;
9235 pConfig->num_deny_mac = 0;
9236
9237 /**
9238 * access control policy
9239 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9240 * listed in hostapd.deny file.
9241 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9242 * listed in hostapd.accept file.
9243 */
9244 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9245 {
9246 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9247 }
9248 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9249 {
9250 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9251 }
9252 else
9253 {
9254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9255 "%s:Acl Policy : %d is not supported",
9256 __func__, params->acl_policy);
9257 return -ENOTSUPP;
9258 }
9259
9260 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9261 {
9262 pConfig->num_accept_mac = params->n_acl_entries;
9263 for (i = 0; i < params->n_acl_entries; i++)
9264 {
9265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9266 "** Add ACL MAC entry %i in WhiletList :"
9267 MAC_ADDRESS_STR, i,
9268 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9269
9270 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9271 sizeof(qcmacaddr));
9272 }
9273 }
9274 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9275 {
9276 pConfig->num_deny_mac = params->n_acl_entries;
9277 for (i = 0; i < params->n_acl_entries; i++)
9278 {
9279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9280 "** Add ACL MAC entry %i in BlackList :"
9281 MAC_ADDRESS_STR, i,
9282 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9283
9284 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9285 sizeof(qcmacaddr));
9286 }
9287 }
9288
9289 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9290 {
9291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9292 "%s: SAP Set Mac Acl fail", __func__);
9293 return -EINVAL;
9294 }
9295 }
9296 else
9297 {
9298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9299 "%s: Invalid device_mode = %d",
9300 __func__, pAdapter->device_mode);
9301 return -EINVAL;
9302 }
9303
9304 return 0;
9305}
9306
Leo Chang9056f462013-08-01 19:21:11 -07009307#ifdef WLAN_NL80211_TESTMODE
9308#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009309void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009310(
9311 void *pAdapter,
9312 void *indCont
9313)
9314{
Leo Changd9df8aa2013-09-26 13:32:26 -07009315 tSirLPHBInd *lphbInd;
9316 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009317
9318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009319 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009320
9321 if (NULL == indCont)
9322 {
9323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009324 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009325 return;
9326 }
9327
Leo Changd9df8aa2013-09-26 13:32:26 -07009328 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009329 skb = cfg80211_testmode_alloc_event_skb(
9330 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009331 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009332 GFP_ATOMIC);
9333 if (!skb)
9334 {
9335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9336 "LPHB timeout, NL buffer alloc fail");
9337 return;
9338 }
9339
Leo Changac3ba772013-10-07 09:47:04 -07009340 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009341 {
9342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9343 "WLAN_HDD_TM_ATTR_CMD put fail");
9344 goto nla_put_failure;
9345 }
Leo Changac3ba772013-10-07 09:47:04 -07009346 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009347 {
9348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9349 "WLAN_HDD_TM_ATTR_TYPE put fail");
9350 goto nla_put_failure;
9351 }
Leo Changac3ba772013-10-07 09:47:04 -07009352 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009353 sizeof(tSirLPHBInd), lphbInd))
9354 {
9355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9356 "WLAN_HDD_TM_ATTR_DATA put fail");
9357 goto nla_put_failure;
9358 }
Leo Chang9056f462013-08-01 19:21:11 -07009359 cfg80211_testmode_event(skb, GFP_ATOMIC);
9360 return;
9361
9362nla_put_failure:
9363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9364 "NLA Put fail");
9365 kfree_skb(skb);
9366
9367 return;
9368}
9369#endif /* FEATURE_WLAN_LPHB */
9370
9371static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9372{
9373 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9374 int err = 0;
9375#ifdef FEATURE_WLAN_LPHB
9376 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009377 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009378#endif /* FEATURE_WLAN_LPHB */
9379
9380 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9381 if (err)
9382 {
9383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9384 "%s Testmode INV ATTR", __func__);
9385 return err;
9386 }
9387
9388 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9389 {
9390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9391 "%s Testmode INV CMD", __func__);
9392 return -EINVAL;
9393 }
9394
9395 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9396 {
9397#ifdef FEATURE_WLAN_LPHB
9398 /* Low Power Heartbeat configuration request */
9399 case WLAN_HDD_TM_CMD_WLAN_HB:
9400 {
9401 int buf_len;
9402 void *buf;
9403 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009404 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009405
9406 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9407 {
9408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9409 "%s Testmode INV DATA", __func__);
9410 return -EINVAL;
9411 }
9412
9413 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9414 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009415
9416 hb_params_temp =(tSirLPHBReq *)buf;
9417 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9418 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9419 return -EINVAL;
9420
Leo Chang9056f462013-08-01 19:21:11 -07009421 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9422 if (NULL == hb_params)
9423 {
9424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9425 "%s Request Buffer Alloc Fail", __func__);
9426 return -EINVAL;
9427 }
9428
9429 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009430 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9431 hb_params,
9432 wlan_hdd_cfg80211_lphb_ind_handler);
9433 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009434 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9436 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009437 vos_mem_free(hb_params);
9438 }
Leo Chang9056f462013-08-01 19:21:11 -07009439 return 0;
9440 }
9441#endif /* FEATURE_WLAN_LPHB */
9442 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9444 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009445 return -EOPNOTSUPP;
9446 }
9447
9448 return err;
9449}
9450#endif /* CONFIG_NL80211_TESTMODE */
9451
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309452static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9453 struct net_device *dev,
9454 int idx, struct survey_info *survey)
9455{
9456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9457 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309458 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309459 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309460 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309461 v_S7_t snr,rssi;
9462 int status, i, j, filled = 0;
9463
9464 ENTER();
9465
9466
9467 if (NULL == pAdapter)
9468 {
9469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9470 "%s: HDD adapter is Null", __func__);
9471 return -ENODEV;
9472 }
9473
9474 if (NULL == wiphy)
9475 {
9476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9477 "%s: wiphy is Null", __func__);
9478 return -ENODEV;
9479 }
9480
9481 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9482 status = wlan_hdd_validate_context(pHddCtx);
9483
9484 if (0 != status)
9485 {
9486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9487 "%s: HDD context is not valid", __func__);
9488 return status;
9489 }
9490
Mihir Sheted9072e02013-08-21 17:02:29 +05309491 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9492
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309493 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309494 0 != pAdapter->survey_idx ||
9495 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309496 {
9497 /* The survey dump ops when implemented completely is expected to
9498 * return a survey of all channels and the ops is called by the
9499 * kernel with incremental values of the argument 'idx' till it
9500 * returns -ENONET. But we can only support the survey for the
9501 * operating channel for now. survey_idx is used to track
9502 * that the ops is called only once and then return -ENONET for
9503 * the next iteration
9504 */
9505 pAdapter->survey_idx = 0;
9506 return -ENONET;
9507 }
9508
9509 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9510
9511 wlan_hdd_get_snr(pAdapter, &snr);
9512 wlan_hdd_get_rssi(pAdapter, &rssi);
9513
9514 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9515 hdd_wlan_get_freq(channel, &freq);
9516
9517
9518 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9519 {
9520 if (NULL == wiphy->bands[i])
9521 {
9522 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9523 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9524 continue;
9525 }
9526
9527 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9528 {
9529 struct ieee80211_supported_band *band = wiphy->bands[i];
9530
9531 if (band->channels[j].center_freq == (v_U16_t)freq)
9532 {
9533 survey->channel = &band->channels[j];
9534 /* The Rx BDs contain SNR values in dB for the received frames
9535 * while the supplicant expects noise. So we calculate and
9536 * return the value of noise (dBm)
9537 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9538 */
9539 survey->noise = rssi - snr;
9540 survey->filled = SURVEY_INFO_NOISE_DBM;
9541 filled = 1;
9542 }
9543 }
9544 }
9545
9546 if (filled)
9547 pAdapter->survey_idx = 1;
9548 else
9549 {
9550 pAdapter->survey_idx = 0;
9551 return -ENONET;
9552 }
9553
9554 return 0;
9555}
9556
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309557/*
9558 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9559 * this is called when cfg80211 driver resume
9560 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9561 */
9562int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9563{
9564 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9565 hdd_adapter_t *pAdapter;
9566 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9567 VOS_STATUS status = VOS_STATUS_SUCCESS;
9568
9569 ENTER();
9570
9571 if ( NULL == pHddCtx )
9572 {
9573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9574 "%s: HddCtx validation failed", __func__);
9575 return 0;
9576 }
9577
9578 if (pHddCtx->isLogpInProgress)
9579 {
9580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9581 "%s: LOGP in Progress. Ignore!!!", __func__);
9582 return 0;
9583 }
9584
9585 if (pHddCtx->isLoadUnloadInProgress)
9586 {
9587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9588 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9589 return 0;
9590 }
9591
9592 spin_lock(&pHddCtx->schedScan_lock);
9593 pHddCtx->isWiphySuspended = FALSE;
9594 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9595 {
9596 spin_unlock(&pHddCtx->schedScan_lock);
9597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9598 "%s: Return resume is not due to PNO indication", __func__);
9599 return 0;
9600 }
9601 // Reset flag to avoid updatating cfg80211 data old results again
9602 pHddCtx->isSchedScanUpdatePending = FALSE;
9603 spin_unlock(&pHddCtx->schedScan_lock);
9604
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309605
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309606 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9607
9608 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9609 {
9610 pAdapter = pAdapterNode->pAdapter;
9611 if ( (NULL != pAdapter) &&
9612 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9613 {
9614 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309615 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9617 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309618 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309619 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309620 {
9621 /* Acquire wakelock to handle the case where APP's tries to
9622 * suspend immediately after updating the scan results. Whis
9623 * results in app's is in suspended state and not able to
9624 * process the connect request to AP
9625 */
9626 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309627 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309628 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309629
9630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9631 "%s : cfg80211 scan result database updated", __func__);
9632
9633 return 0;
9634
9635 }
9636 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9637 pAdapterNode = pNext;
9638 }
9639
9640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9641 "%s: Failed to find Adapter", __func__);
9642 return 0;
9643}
9644
9645/*
9646 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9647 * this is called when cfg80211 driver suspends
9648 */
9649int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9650 struct cfg80211_wowlan *wow)
9651{
9652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9653
9654 ENTER();
9655 if (NULL == pHddCtx)
9656 {
9657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9658 "%s: HddCtx validation failed", __func__);
9659 return 0;
9660 }
9661
9662 pHddCtx->isWiphySuspended = TRUE;
9663
9664 EXIT();
9665
9666 return 0;
9667}
9668
Jeff Johnson295189b2012-06-20 16:38:30 -07009669/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309670static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009671{
9672 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9673 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9674 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9675 .change_station = wlan_hdd_change_station,
9676#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9677 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9678 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9679 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009680#else
9681 .start_ap = wlan_hdd_cfg80211_start_ap,
9682 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9683 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009684#endif
9685 .change_bss = wlan_hdd_cfg80211_change_bss,
9686 .add_key = wlan_hdd_cfg80211_add_key,
9687 .get_key = wlan_hdd_cfg80211_get_key,
9688 .del_key = wlan_hdd_cfg80211_del_key,
9689 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009690#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009692#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 .scan = wlan_hdd_cfg80211_scan,
9694 .connect = wlan_hdd_cfg80211_connect,
9695 .disconnect = wlan_hdd_cfg80211_disconnect,
9696 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9697 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9698 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9699 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9700 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9702 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
9703 .mgmt_tx = wlan_hdd_action,
9704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9705 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9706 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9707 .set_txq_params = wlan_hdd_set_txq_params,
9708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 .get_station = wlan_hdd_cfg80211_get_station,
9710 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9711 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009712 .add_station = wlan_hdd_cfg80211_add_station,
9713#ifdef FEATURE_WLAN_LFR
9714 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9715 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9716 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9717#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009718#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9719 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9720#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009721#ifdef FEATURE_WLAN_TDLS
9722 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9723 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9724#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309725#ifdef WLAN_FEATURE_GTK_OFFLOAD
9726 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9727#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309728#ifdef FEATURE_WLAN_SCAN_PNO
9729 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9730 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9731#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309732 .resume = wlan_hdd_cfg80211_resume_wlan,
9733 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309734 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009735#ifdef WLAN_NL80211_TESTMODE
9736 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9737#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309738 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009739};
9740