blob: 62694e6d0fb1d9fbcc9874035ede02b6a0e4b059 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070084#ifdef WLAN_BTAMP_FEATURE
85#include "bap_hdd_misc.h"
86#endif
87#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080088#ifdef FEATURE_WLAN_TDLS
89#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053090#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053091#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053093#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070094#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095
96#define g_mode_rates_size (12)
97#define a_mode_rates_size (8)
98#define FREQ_BASE_80211G (2407)
99#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700100#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530101#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800103 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700104
105#define HDD2GHZCHAN(freq, chan, flag) { \
106 .band = IEEE80211_BAND_2GHZ, \
107 .center_freq = (freq), \
108 .hw_value = (chan),\
109 .flags = (flag), \
110 .max_antenna_gain = 0 ,\
111 .max_power = 30, \
112}
113
114#define HDD5GHZCHAN(freq, chan, flag) { \
115 .band = IEEE80211_BAND_5GHZ, \
116 .center_freq = (freq), \
117 .hw_value = (chan),\
118 .flags = (flag), \
119 .max_antenna_gain = 0 ,\
120 .max_power = 30, \
121}
122
123#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
124{\
125 .bitrate = rate, \
126 .hw_value = rate_id, \
127 .flags = flag, \
128}
129
Lee Hoonkic1262f22013-01-24 21:59:00 -0800130#ifndef WLAN_FEATURE_TDLS_DEBUG
131#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
132#else
133#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
134#endif
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
142
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530143static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700144{
145 WLAN_CIPHER_SUITE_WEP40,
146 WLAN_CIPHER_SUITE_WEP104,
147 WLAN_CIPHER_SUITE_TKIP,
148#ifdef FEATURE_WLAN_CCX
149#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
150 WLAN_CIPHER_SUITE_KRK,
151 WLAN_CIPHER_SUITE_CCMP,
152#else
153 WLAN_CIPHER_SUITE_CCMP,
154#endif
155#ifdef FEATURE_WLAN_WAPI
156 WLAN_CIPHER_SUITE_SMS4,
157#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700158#ifdef WLAN_FEATURE_11W
159 WLAN_CIPHER_SUITE_AES_CMAC,
160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161};
162
163static inline int is_broadcast_ether_addr(const u8 *addr)
164{
165 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
166 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
167}
168
169static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530170{
Jeff Johnson295189b2012-06-20 16:38:30 -0700171 HDD2GHZCHAN(2412, 1, 0) ,
172 HDD2GHZCHAN(2417, 2, 0) ,
173 HDD2GHZCHAN(2422, 3, 0) ,
174 HDD2GHZCHAN(2427, 4, 0) ,
175 HDD2GHZCHAN(2432, 5, 0) ,
176 HDD2GHZCHAN(2437, 6, 0) ,
177 HDD2GHZCHAN(2442, 7, 0) ,
178 HDD2GHZCHAN(2447, 8, 0) ,
179 HDD2GHZCHAN(2452, 9, 0) ,
180 HDD2GHZCHAN(2457, 10, 0) ,
181 HDD2GHZCHAN(2462, 11, 0) ,
182 HDD2GHZCHAN(2467, 12, 0) ,
183 HDD2GHZCHAN(2472, 13, 0) ,
184 HDD2GHZCHAN(2484, 14, 0) ,
185};
186
Jeff Johnson295189b2012-06-20 16:38:30 -0700187static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
188{
189 HDD2GHZCHAN(2412, 1, 0) ,
190 HDD2GHZCHAN(2437, 6, 0) ,
191 HDD2GHZCHAN(2462, 11, 0) ,
192};
Jeff Johnson295189b2012-06-20 16:38:30 -0700193
194static struct ieee80211_channel hdd_channels_5_GHZ[] =
195{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700196 HDD5GHZCHAN(4920, 240, 0) ,
197 HDD5GHZCHAN(4940, 244, 0) ,
198 HDD5GHZCHAN(4960, 248, 0) ,
199 HDD5GHZCHAN(4980, 252, 0) ,
200 HDD5GHZCHAN(5040, 208, 0) ,
201 HDD5GHZCHAN(5060, 212, 0) ,
202 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD5GHZCHAN(5180, 36, 0) ,
204 HDD5GHZCHAN(5200, 40, 0) ,
205 HDD5GHZCHAN(5220, 44, 0) ,
206 HDD5GHZCHAN(5240, 48, 0) ,
207 HDD5GHZCHAN(5260, 52, 0) ,
208 HDD5GHZCHAN(5280, 56, 0) ,
209 HDD5GHZCHAN(5300, 60, 0) ,
210 HDD5GHZCHAN(5320, 64, 0) ,
211 HDD5GHZCHAN(5500,100, 0) ,
212 HDD5GHZCHAN(5520,104, 0) ,
213 HDD5GHZCHAN(5540,108, 0) ,
214 HDD5GHZCHAN(5560,112, 0) ,
215 HDD5GHZCHAN(5580,116, 0) ,
216 HDD5GHZCHAN(5600,120, 0) ,
217 HDD5GHZCHAN(5620,124, 0) ,
218 HDD5GHZCHAN(5640,128, 0) ,
219 HDD5GHZCHAN(5660,132, 0) ,
220 HDD5GHZCHAN(5680,136, 0) ,
221 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800222#ifdef FEATURE_WLAN_CH144
223 HDD5GHZCHAN(5720,144, 0) ,
224#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700225 HDD5GHZCHAN(5745,149, 0) ,
226 HDD5GHZCHAN(5765,153, 0) ,
227 HDD5GHZCHAN(5785,157, 0) ,
228 HDD5GHZCHAN(5805,161, 0) ,
229 HDD5GHZCHAN(5825,165, 0) ,
230};
231
232static struct ieee80211_rate g_mode_rates[] =
233{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530234 HDD_G_MODE_RATETAB(10, 0x1, 0),
235 HDD_G_MODE_RATETAB(20, 0x2, 0),
236 HDD_G_MODE_RATETAB(55, 0x4, 0),
237 HDD_G_MODE_RATETAB(110, 0x8, 0),
238 HDD_G_MODE_RATETAB(60, 0x10, 0),
239 HDD_G_MODE_RATETAB(90, 0x20, 0),
240 HDD_G_MODE_RATETAB(120, 0x40, 0),
241 HDD_G_MODE_RATETAB(180, 0x80, 0),
242 HDD_G_MODE_RATETAB(240, 0x100, 0),
243 HDD_G_MODE_RATETAB(360, 0x200, 0),
244 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530246};
Jeff Johnson295189b2012-06-20 16:38:30 -0700247
248static struct ieee80211_rate a_mode_rates[] =
249{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530250 HDD_G_MODE_RATETAB(60, 0x10, 0),
251 HDD_G_MODE_RATETAB(90, 0x20, 0),
252 HDD_G_MODE_RATETAB(120, 0x40, 0),
253 HDD_G_MODE_RATETAB(180, 0x80, 0),
254 HDD_G_MODE_RATETAB(240, 0x100, 0),
255 HDD_G_MODE_RATETAB(360, 0x200, 0),
256 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD_G_MODE_RATETAB(540, 0x800, 0),
258};
259
260static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
261{
262 .channels = hdd_channels_2_4_GHZ,
263 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
264 .band = IEEE80211_BAND_2GHZ,
265 .bitrates = g_mode_rates,
266 .n_bitrates = g_mode_rates_size,
267 .ht_cap.ht_supported = 1,
268 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
269 | IEEE80211_HT_CAP_GRN_FLD
270 | IEEE80211_HT_CAP_DSSSCCK40
271 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
272 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
273 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
274 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
275 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
276 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
277};
278
Jeff Johnson295189b2012-06-20 16:38:30 -0700279static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
280{
281 .channels = hdd_social_channels_2_4_GHZ,
282 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
283 .band = IEEE80211_BAND_2GHZ,
284 .bitrates = g_mode_rates,
285 .n_bitrates = g_mode_rates_size,
286 .ht_cap.ht_supported = 1,
287 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
288 | IEEE80211_HT_CAP_GRN_FLD
289 | IEEE80211_HT_CAP_DSSSCCK40
290 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
291 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
292 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
293 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
294 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
295 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
296};
Jeff Johnson295189b2012-06-20 16:38:30 -0700297
298static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
299{
300 .channels = hdd_channels_5_GHZ,
301 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
302 .band = IEEE80211_BAND_5GHZ,
303 .bitrates = a_mode_rates,
304 .n_bitrates = a_mode_rates_size,
305 .ht_cap.ht_supported = 1,
306 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
307 | IEEE80211_HT_CAP_GRN_FLD
308 | IEEE80211_HT_CAP_DSSSCCK40
309 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
310 | IEEE80211_HT_CAP_SGI_40
311 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
312 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
313 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
314 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
315 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
316 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
317};
318
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530319/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 TX/RX direction for each kind of interface */
321static const struct ieee80211_txrx_stypes
322wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
323 [NL80211_IFTYPE_STATION] = {
324 .tx = 0xffff,
325 .rx = BIT(SIR_MAC_MGMT_ACTION) |
326 BIT(SIR_MAC_MGMT_PROBE_REQ),
327 },
328 [NL80211_IFTYPE_AP] = {
329 .tx = 0xffff,
330 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
331 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
332 BIT(SIR_MAC_MGMT_PROBE_REQ) |
333 BIT(SIR_MAC_MGMT_DISASSOC) |
334 BIT(SIR_MAC_MGMT_AUTH) |
335 BIT(SIR_MAC_MGMT_DEAUTH) |
336 BIT(SIR_MAC_MGMT_ACTION),
337 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700338 [NL80211_IFTYPE_ADHOC] = {
339 .tx = 0xffff,
340 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
341 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
342 BIT(SIR_MAC_MGMT_PROBE_REQ) |
343 BIT(SIR_MAC_MGMT_DISASSOC) |
344 BIT(SIR_MAC_MGMT_AUTH) |
345 BIT(SIR_MAC_MGMT_DEAUTH) |
346 BIT(SIR_MAC_MGMT_ACTION),
347 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 [NL80211_IFTYPE_P2P_CLIENT] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_P2P_GO] = {
354 /* This is also same as for SoftAP */
355 .tx = 0xffff,
356 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ) |
359 BIT(SIR_MAC_MGMT_DISASSOC) |
360 BIT(SIR_MAC_MGMT_AUTH) |
361 BIT(SIR_MAC_MGMT_DEAUTH) |
362 BIT(SIR_MAC_MGMT_ACTION),
363 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700364};
365
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800367static const struct ieee80211_iface_limit
368wlan_hdd_iface_limit[] = {
369 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800370 /* max = 3 ; Our driver create two interfaces during driver init
371 * wlan0 and p2p0 interfaces. p2p0 is considered as station
372 * interface until a group is formed. In JB architecture, once the
373 * group is formed, interface type of p2p0 is changed to P2P GO or
374 * Client.
375 * When supplicant remove the group, it first issue a set interface
376 * cmd to change the mode back to Station. In JB this works fine as
377 * we advertize two station type interface during driver init.
378 * Some vendors create separate interface for P2P GO/Client,
379 * after group formation(Third one). But while group remove
380 * supplicant first tries to change the mode(3rd interface) to STATION
381 * But as we advertized only two sta type interfaces nl80211 was
382 * returning error for the third one which was leading to failure in
383 * delete interface. Ideally while removing the group, supplicant
384 * should not try to change the 3rd interface mode to Station type.
385 * Till we get a fix in wpa_supplicant, we advertize max STA
386 * interface type to 3
387 */
388 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389 .types = BIT(NL80211_IFTYPE_STATION),
390 },
391 {
392 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700393 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800394 },
395 {
396 .max = 1,
397 .types = BIT(NL80211_IFTYPE_P2P_GO) |
398 BIT(NL80211_IFTYPE_P2P_CLIENT),
399 },
400};
401
402/* By default, only single channel concurrency is allowed */
403static struct ieee80211_iface_combination
404wlan_hdd_iface_combination = {
405 .limits = wlan_hdd_iface_limit,
406 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800407 /*
408 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
409 * and p2p0 interfaces during driver init
410 * Some vendors create separate interface for P2P operations.
411 * wlan0: STA interface
412 * p2p0: P2P Device interface, action frames goes
413 * through this interface.
414 * p2p-xx: P2P interface, After GO negotiation this interface is
415 * created for p2p operations(GO/CLIENT interface).
416 */
417 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800418 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
419 .beacon_int_infra_match = false,
420};
421#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423static struct cfg80211_ops wlan_hdd_cfg80211_ops;
424
425/* Data rate 100KBPS based on IE Index */
426struct index_data_rate_type
427{
428 v_U8_t beacon_rate_index;
429 v_U16_t supported_rate[4];
430};
431
432/* 11B, 11G Rate table include Basic rate and Extended rate
433 The IDX field is the rate index
434 The HI field is the rate when RSSI is strong or being ignored
435 (in this case we report actual rate)
436 The MID field is the rate when RSSI is moderate
437 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
438 The LO field is the rate when RSSI is low
439 (in this case we don't report rates, actual current rate used)
440 */
441static const struct
442{
443 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700444 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700445} supported_data_rate[] =
446{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447/* IDX HI HM LM LO (RSSI-based index */
448 {2, { 10, 10, 10, 0}},
449 {4, { 20, 20, 10, 0}},
450 {11, { 55, 20, 10, 0}},
451 {12, { 60, 55, 20, 0}},
452 {18, { 90, 55, 20, 0}},
453 {22, {110, 55, 20, 0}},
454 {24, {120, 90, 60, 0}},
455 {36, {180, 120, 60, 0}},
456 {44, {220, 180, 60, 0}},
457 {48, {240, 180, 90, 0}},
458 {66, {330, 180, 90, 0}},
459 {72, {360, 240, 90, 0}},
460 {96, {480, 240, 120, 0}},
461 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700462};
463
464/* MCS Based rate table */
465static struct index_data_rate_type supported_mcs_rate[] =
466{
467/* MCS L20 L40 S20 S40 */
468 {0, {65, 135, 72, 150}},
469 {1, {130, 270, 144, 300}},
470 {2, {195, 405, 217, 450}},
471 {3, {260, 540, 289, 600}},
472 {4, {390, 810, 433, 900}},
473 {5, {520, 1080, 578, 1200}},
474 {6, {585, 1215, 650, 1350}},
475 {7, {650, 1350, 722, 1500}}
476};
477
Leo Chang6f8870f2013-03-26 18:11:36 -0700478#ifdef WLAN_FEATURE_11AC
479
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530480#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700481
482struct index_vht_data_rate_type
483{
484 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530485 v_U16_t supported_VHT80_rate[2];
486 v_U16_t supported_VHT40_rate[2];
487 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700488};
489
490typedef enum
491{
492 DATA_RATE_11AC_MAX_MCS_7,
493 DATA_RATE_11AC_MAX_MCS_8,
494 DATA_RATE_11AC_MAX_MCS_9,
495 DATA_RATE_11AC_MAX_MCS_NA
496} eDataRate11ACMaxMcs;
497
498/* MCS Based VHT rate table */
499static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
500{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530501/* MCS L80 S80 L40 S40 L20 S40*/
502 {0, {293, 325}, {135, 150}, {65, 72}},
503 {1, {585, 650}, {270, 300}, {130, 144}},
504 {2, {878, 975}, {405, 450}, {195, 217}},
505 {3, {1170, 1300}, {540, 600}, {260, 289}},
506 {4, {1755, 1950}, {810, 900}, {390, 433}},
507 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
508 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
509 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
510 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
511 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700512};
513#endif /* WLAN_FEATURE_11AC */
514
Jeff Johnson295189b2012-06-20 16:38:30 -0700515extern struct net_device_ops net_ops_struct;
516
Leo Chang9056f462013-08-01 19:21:11 -0700517#ifdef WLAN_NL80211_TESTMODE
518enum wlan_hdd_tm_attr
519{
520 WLAN_HDD_TM_ATTR_INVALID = 0,
521 WLAN_HDD_TM_ATTR_CMD = 1,
522 WLAN_HDD_TM_ATTR_DATA = 2,
523 WLAN_HDD_TM_ATTR_TYPE = 3,
524 /* keep last */
525 WLAN_HDD_TM_ATTR_AFTER_LAST,
526 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
527};
528
529enum wlan_hdd_tm_cmd
530{
531 WLAN_HDD_TM_CMD_WLAN_HB = 1,
532};
533
534#define WLAN_HDD_TM_DATA_MAX_LEN 5000
535
536static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
537{
538 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
539 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
540 .len = WLAN_HDD_TM_DATA_MAX_LEN },
541};
542#endif /* WLAN_NL80211_TESTMODE */
543
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800544#ifdef FEATURE_WLAN_CH_AVOID
545/*
546 * FUNCTION: wlan_hdd_send_avoid_freq_event
547 * This is called when wlan driver needs to send vendor specific
548 * avoid frequency range event to userspace
549 */
550int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
551 tHddAvoidFreqList *pAvoidFreqList)
552{
553 struct sk_buff *vendor_event;
554
555 ENTER();
556
557 if (!pHddCtx)
558 {
559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
560 "%s: HDD context is null", __func__);
561 return -1;
562 }
563
564 if (!pAvoidFreqList)
565 {
566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
567 "%s: pAvoidFreqList is null", __func__);
568 return -1;
569 }
570
571 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
572 sizeof(tHddAvoidFreqList),
573 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
574 GFP_KERNEL);
575 if (!vendor_event)
576 {
577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
578 "%s: cfg80211_vendor_event_alloc failed", __func__);
579 return -1;
580 }
581
582 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
583 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
584
585 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
586
587 EXIT();
588 return 0;
589}
590#endif /* FEATURE_WLAN_CH_AVOID */
591
592/* vendor specific events */
593static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
594{
595#ifdef FEATURE_WLAN_CH_AVOID
596 {
597 .vendor_id = QCOM_NL80211_VENDOR_ID,
598 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
599 },
600#endif /* FEATURE_WLAN_CH_AVOID */
601};
602
Jeff Johnson295189b2012-06-20 16:38:30 -0700603/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530604 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530605 * This function is called by hdd_wlan_startup()
606 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700608 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530609struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700610{
611 struct wiphy *wiphy;
612 ENTER();
613
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530614 /*
615 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700616 */
617 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
618
619 if (!wiphy)
620 {
621 /* Print error and jump into err label and free the memory */
622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
623 return NULL;
624 }
625
626 return wiphy;
627}
628
629/*
630 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530631 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700632 * private ioctl to change the band value
633 */
634int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
635{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530636 int i, j;
637 eNVChannelEnabledType channelEnabledState;
638
Jeff Johnsone7245742012-09-05 17:12:55 -0700639 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530640 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530642
643 if (NULL == wiphy->bands[i])
644 {
645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
646 __func__, i);
647 continue;
648 }
649
650 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
651 {
652 struct ieee80211_supported_band *band = wiphy->bands[i];
653
654 channelEnabledState = vos_nv_getChannelEnabledState(
655 band->channels[j].hw_value);
656
657 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
658 {
659 // Enable Social channels for P2P
660 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
661 NV_CHANNEL_ENABLE == channelEnabledState)
662 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
663 else
664 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
665 continue;
666 }
667 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
668 {
669 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
670 continue;
671 }
672
673 if (NV_CHANNEL_DISABLE == channelEnabledState ||
674 NV_CHANNEL_INVALID == channelEnabledState)
675 {
676 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
677 }
678 else if (NV_CHANNEL_DFS == channelEnabledState)
679 {
680 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
681 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
682 }
683 else
684 {
685 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
686 |IEEE80211_CHAN_RADAR);
687 }
688 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 }
690 return 0;
691}
692/*
693 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530694 * This function is called by hdd_wlan_startup()
695 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 * This function is used to initialize and register wiphy structure.
697 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530698int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 struct wiphy *wiphy,
700 hdd_config_t *pCfg
701 )
702{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530703 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530704 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
705
Jeff Johnsone7245742012-09-05 17:12:55 -0700706 ENTER();
707
Jeff Johnson295189b2012-06-20 16:38:30 -0700708 /* Now bind the underlying wlan device with wiphy */
709 set_wiphy_dev(wiphy, dev);
710
711 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700712
Kiet Lam6c583332013-10-14 05:37:09 +0530713#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700714 /* the flag for the other case would be initialzed in
715 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700716 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530717#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700718
Amar Singhalfddc28c2013-09-05 13:03:40 -0700719 /* This will disable updating of NL channels from passive to
720 * active if a beacon is received on passive channel. */
721 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700722
Amar Singhalfddc28c2013-09-05 13:03:40 -0700723
Amar Singhala49cbc52013-10-08 18:37:44 -0700724
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700726 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
727 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
728 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700729 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530730 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700731#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700732
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700733#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
734 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800735#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700736 || pCfg->isFastRoamIniFeatureEnabled
737#endif
738#ifdef FEATURE_WLAN_CCX
739 || pCfg->isCcxIniFeatureEnabled
740#endif
741 )
742 {
743 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
744 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800745#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800746#ifdef FEATURE_WLAN_TDLS
747 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
748 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
749#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530750#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530751 if (pCfg->configPNOScanSupport)
752 {
753 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
754 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
755 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
756 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
757 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530758#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800759
Amar Singhalfddc28c2013-09-05 13:03:40 -0700760#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700761 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
762 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 driver need to determine what to do with both
765 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766
767 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700768#else
769 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700770#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700771
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530772 wiphy->max_scan_ssids = MAX_SCAN_SSID;
773
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530774 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700775
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530776 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
777
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530779 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700780 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 | BIT(NL80211_IFTYPE_P2P_CLIENT)
782 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_AP);
784
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530785 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800786 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
788 if( pCfg->enableMCC )
789 {
790 /* Currently, supports up to two channels */
791 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800792
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530793 if( !pCfg->allowMCCGODiffBI )
794 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 }
797 wiphy->iface_combinations = &wlan_hdd_iface_combination;
798 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800799#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530800 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800801
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 /* Before registering we need to update the ht capabilitied based
803 * on ini values*/
804 if( !pCfg->ShortGI20MhzEnable )
805 {
806 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
807 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
808 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
809 }
810
811 if( !pCfg->ShortGI40MhzEnable )
812 {
813 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
814 }
815
816 if( !pCfg->nChannelBondingMode5GHz )
817 {
818 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
819 }
820
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530821 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530822 if (true == hdd_is_5g_supported(pHddCtx))
823 {
824 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
825 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530826
827 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
828 {
829
830 if (NULL == wiphy->bands[i])
831 {
832 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
833 __func__, i);
834 continue;
835 }
836
837 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
838 {
839 struct ieee80211_supported_band *band = wiphy->bands[i];
840
841 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
842 {
843 // Enable social channels for P2P
844 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
845 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
846 else
847 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
848 continue;
849 }
850 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
851 {
852 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
853 continue;
854 }
855 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700856 }
857 /*Initialise the supported cipher suite details*/
858 wiphy->cipher_suites = hdd_cipher_suites;
859 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
860
861 /*signal strength in mBm (100*dBm) */
862 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
863
864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700865 wiphy->max_remain_on_channel_duration = 1000;
866#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700867
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800868 wiphy->n_vendor_commands = 0;
869 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
870 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
871
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530872 EXIT();
873 return 0;
874}
875
876/* In this function we are registering wiphy. */
877int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
878{
879 ENTER();
880 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 if (0 > wiphy_register(wiphy))
882 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530883 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
885 return -EIO;
886 }
887
888 EXIT();
889 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530890}
Jeff Johnson295189b2012-06-20 16:38:30 -0700891
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530892/* In this function we are updating channel list when,
893 regulatory domain is FCC and country code is US.
894 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
895 As per FCC smart phone is not a indoor device.
896 GO should not opeate on indoor channels */
897void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
898{
899 int j;
900 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
901 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
902 //Default counrtycode from NV at the time of wiphy initialization.
903 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
904 &defaultCountryCode[0]))
905 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700906 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530907 }
908 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
909 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
911 {
912 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
913 return;
914 }
915 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
916 {
917 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
918 // Mark UNII -1 band channel as passive
919 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
920 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
921 }
922 }
923}
924
Jeff Johnson295189b2012-06-20 16:38:30 -0700925/* In this function we will do all post VOS start initialization.
926 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530927 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700928*/
929void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
930{
Jeff Johnson295189b2012-06-20 16:38:30 -0700931 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
932 /* Register for all P2P action, public action etc frames */
933 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
934
Jeff Johnsone7245742012-09-05 17:12:55 -0700935 ENTER();
936
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 /* Right now we are registering these frame when driver is getting
938 initialized. Once we will move to 2.6.37 kernel, in which we have
939 frame register ops, we will move this code as a part of that */
940 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530941 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
943
944 /* GAS Initial Response */
945 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
946 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530947
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 /* GAS Comeback Request */
949 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
950 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
951
952 /* GAS Comeback Response */
953 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
954 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
955
956 /* P2P Public Action */
957 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530958 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 P2P_PUBLIC_ACTION_FRAME_SIZE );
960
961 /* P2P Action */
962 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
963 (v_U8_t*)P2P_ACTION_FRAME,
964 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700965
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530966 /* WNM BSS Transition Request frame */
967 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
968 (v_U8_t*)WNM_BSS_ACTION_FRAME,
969 WNM_BSS_ACTION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700970}
971
972void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
973{
Jeff Johnson295189b2012-06-20 16:38:30 -0700974 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
975 /* Register for all P2P action, public action etc frames */
976 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
977
Jeff Johnsone7245742012-09-05 17:12:55 -0700978 ENTER();
979
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 /* Right now we are registering these frame when driver is getting
981 initialized. Once we will move to 2.6.37 kernel, in which we have
982 frame register ops, we will move this code as a part of that */
983 /* GAS Initial Request */
984
985 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
986 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
987
988 /* GAS Initial Response */
989 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
990 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530991
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 /* GAS Comeback Request */
993 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
994 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
995
996 /* GAS Comeback Response */
997 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
998 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
999
1000 /* P2P Public Action */
1001 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301002 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 P2P_PUBLIC_ACTION_FRAME_SIZE );
1004
1005 /* P2P Action */
1006 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1007 (v_U8_t*)P2P_ACTION_FRAME,
1008 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07001009
1010#ifdef WLAN_FEATURE_11W
1011 /* SA Query Response Action Frame */
1012 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1013 (v_U8_t*)SA_QUERY_FRAME_RSP,
1014 SA_QUERY_FRAME_RSP_SIZE );
1015#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001016}
1017
1018#ifdef FEATURE_WLAN_WAPI
1019void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1020 const u8 *mac_addr, u8 *key , int key_Len)
1021{
1022 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1023 tCsrRoamSetKey setKey;
1024 v_BOOL_t isConnected = TRUE;
1025 int status = 0;
1026 v_U32_t roamId= 0xFF;
1027 tANI_U8 *pKeyPtr = NULL;
1028 int n = 0;
1029
Arif Hussain6d2a3322013-11-17 19:50:10 -08001030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 __func__,pAdapter->device_mode);
1032
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301033 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 setKey.keyId = key_index; // Store Key ID
1035 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1036 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1037 setKey.paeRole = 0 ; // the PAE role
1038 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1039 {
1040 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1041 }
1042 else
1043 {
1044 isConnected = hdd_connIsConnected(pHddStaCtx);
1045 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1046 }
1047 setKey.keyLength = key_Len;
1048 pKeyPtr = setKey.Key;
1049 memcpy( pKeyPtr, key, key_Len);
1050
Arif Hussain6d2a3322013-11-17 19:50:10 -08001051 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 __func__, key_Len);
1053 for (n = 0 ; n < key_Len; n++)
1054 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1055 __func__,n,setKey.Key[n]);
1056
1057 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1058 if ( isConnected )
1059 {
1060 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1061 pAdapter->sessionId, &setKey, &roamId );
1062 }
1063 if ( status != 0 )
1064 {
1065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1066 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1067 __LINE__, status );
1068 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1069 }
1070}
1071#endif /* FEATURE_WLAN_WAPI*/
1072
1073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301074int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 beacon_data_t **ppBeacon,
1076 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001077#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301078int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001079 beacon_data_t **ppBeacon,
1080 struct cfg80211_beacon_data *params,
1081 int dtim_period)
1082#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301083{
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 int size;
1085 beacon_data_t *beacon = NULL;
1086 beacon_data_t *old = NULL;
1087 int head_len,tail_len;
1088
Jeff Johnsone7245742012-09-05 17:12:55 -07001089 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301091 {
1092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1093 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001094 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001096
1097 old = pAdapter->sessionCtx.ap.beacon;
1098
1099 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301100 {
1101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1102 FL("session(%d) old and new heads points to NULL"),
1103 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301105 }
1106
1107 if (params->tail && !params->tail_len)
1108 {
1109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1110 FL("tail_len is zero but tail is not NULL"));
1111 return -EINVAL;
1112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001113
Jeff Johnson295189b2012-06-20 16:38:30 -07001114#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1115 /* Kernel 3.0 is not updating dtim_period for set beacon */
1116 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301117 {
1118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1119 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001122#endif
1123
1124 if(params->head)
1125 head_len = params->head_len;
1126 else
1127 head_len = old->head_len;
1128
1129 if(params->tail || !old)
1130 tail_len = params->tail_len;
1131 else
1132 tail_len = old->tail_len;
1133
1134 size = sizeof(beacon_data_t) + head_len + tail_len;
1135
1136 beacon = kzalloc(size, GFP_KERNEL);
1137
1138 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301139 {
1140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1141 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001144
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001145#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001146 if(params->dtim_period || !old )
1147 beacon->dtim_period = params->dtim_period;
1148 else
1149 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001150#else
1151 if(dtim_period || !old )
1152 beacon->dtim_period = dtim_period;
1153 else
1154 beacon->dtim_period = old->dtim_period;
1155#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301156
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1158 beacon->tail = beacon->head + head_len;
1159 beacon->head_len = head_len;
1160 beacon->tail_len = tail_len;
1161
1162 if(params->head) {
1163 memcpy (beacon->head,params->head,beacon->head_len);
1164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301165 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 if(old)
1167 memcpy (beacon->head,old->head,beacon->head_len);
1168 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301169
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 if(params->tail) {
1171 memcpy (beacon->tail,params->tail,beacon->tail_len);
1172 }
1173 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301174 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 memcpy (beacon->tail,old->tail,beacon->tail_len);
1176 }
1177
1178 *ppBeacon = beacon;
1179
1180 kfree(old);
1181
1182 return 0;
1183
1184}
Jeff Johnson295189b2012-06-20 16:38:30 -07001185
1186v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1187{
1188 int left = length;
1189 v_U8_t *ptr = pIes;
1190 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301191
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301193 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 elem_id = ptr[0];
1195 elem_len = ptr[1];
1196 left -= 2;
1197 if(elem_len > left)
1198 {
1199 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001200 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 eid,elem_len,left);
1202 return NULL;
1203 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301204 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001205 {
1206 return ptr;
1207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301208
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 left -= elem_len;
1210 ptr += (elem_len + 2);
1211 }
1212 return NULL;
1213}
1214
Jeff Johnson295189b2012-06-20 16:38:30 -07001215/* Check if rate is 11g rate or not */
1216static int wlan_hdd_rate_is_11g(u8 rate)
1217{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001218 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 u8 i;
1220 for (i = 0; i < 8; i++)
1221 {
1222 if(rate == gRateArray[i])
1223 return TRUE;
1224 }
1225 return FALSE;
1226}
1227
1228/* Check for 11g rate and set proper 11g only mode */
1229static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1230 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1231{
1232 u8 i, num_rates = pIe[0];
1233
1234 pIe += 1;
1235 for ( i = 0; i < num_rates; i++)
1236 {
1237 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1238 {
1239 /* If rate set have 11g rate than change the mode to 11G */
1240 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1241 if (pIe[i] & BASIC_RATE_MASK)
1242 {
1243 /* If we have 11g rate as basic rate, it means mode
1244 is 11g only mode.
1245 */
1246 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1247 *pCheckRatesfor11g = FALSE;
1248 }
1249 }
1250 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1251 {
1252 *require_ht = TRUE;
1253 }
1254 }
1255 return;
1256}
1257
1258static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1259{
1260 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1261 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1262 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1263 u8 checkRatesfor11g = TRUE;
1264 u8 require_ht = FALSE;
1265 u8 *pIe=NULL;
1266
1267 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1268
1269 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1270 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1271 if (pIe != NULL)
1272 {
1273 pIe += 1;
1274 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1275 &pConfig->SapHw_mode);
1276 }
1277
1278 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1279 WLAN_EID_EXT_SUPP_RATES);
1280 if (pIe != NULL)
1281 {
1282
1283 pIe += 1;
1284 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1285 &pConfig->SapHw_mode);
1286 }
1287
1288 if( pConfig->channel > 14 )
1289 {
1290 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1291 }
1292
1293 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1294 WLAN_EID_HT_CAPABILITY);
1295
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301296 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 {
1298 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1299 if(require_ht)
1300 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1301 }
1302}
1303
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301304static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1305 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1306{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001307 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301308 v_U8_t *pIe = NULL;
1309 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1310
1311 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1312 pBeacon->tail, pBeacon->tail_len);
1313
1314 if (pIe)
1315 {
1316 ielen = pIe[1] + 2;
1317 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1318 {
1319 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1320 }
1321 else
1322 {
1323 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1324 return -EINVAL;
1325 }
1326 *total_ielen += ielen;
1327 }
1328 return 0;
1329}
1330
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001331static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1332 v_U8_t *genie, v_U8_t *total_ielen)
1333{
1334 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1335 int left = pBeacon->tail_len;
1336 v_U8_t *ptr = pBeacon->tail;
1337 v_U8_t elem_id, elem_len;
1338 v_U16_t ielen = 0;
1339
1340 if ( NULL == ptr || 0 == left )
1341 return;
1342
1343 while (left >= 2)
1344 {
1345 elem_id = ptr[0];
1346 elem_len = ptr[1];
1347 left -= 2;
1348 if (elem_len > left)
1349 {
1350 hddLog( VOS_TRACE_LEVEL_ERROR,
1351 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1352 elem_id, elem_len, left);
1353 return;
1354 }
1355 if (IE_EID_VENDOR == elem_id)
1356 {
1357 /* skipping the VSIE's which we don't want to include or
1358 * it will be included by existing code
1359 */
1360 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1361#ifdef WLAN_FEATURE_WFD
1362 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1363#endif
1364 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1365 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1366 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1367 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1368 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1369 {
1370 ielen = ptr[1] + 2;
1371 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1372 {
1373 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1374 *total_ielen += ielen;
1375 }
1376 else
1377 {
1378 hddLog( VOS_TRACE_LEVEL_ERROR,
1379 "IE Length is too big "
1380 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1381 elem_id, elem_len, *total_ielen);
1382 }
1383 }
1384 }
1385
1386 left -= elem_len;
1387 ptr += (elem_len + 2);
1388 }
1389 return;
1390}
1391
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001392#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001393static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1394 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001395#else
1396static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1397 struct cfg80211_beacon_data *params)
1398#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001399{
1400 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301401 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001403 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001404
1405 genie = vos_mem_malloc(MAX_GENIE_LEN);
1406
1407 if(genie == NULL) {
1408
1409 return -ENOMEM;
1410 }
1411
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301412 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1413 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001414 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301415 hddLog(LOGE,
1416 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301417 ret = -EINVAL;
1418 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001419 }
1420
1421#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301422 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1423 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1424 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301425 hddLog(LOGE,
1426 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301427 ret = -EINVAL;
1428 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 }
1430#endif
1431
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301432 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1433 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001434 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301435 hddLog(LOGE,
1436 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301437 ret = -EINVAL;
1438 goto done;
1439 }
1440
1441 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1442 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001443 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001445
1446 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1447 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1448 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1449 {
1450 hddLog(LOGE,
1451 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001452 ret = -EINVAL;
1453 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001454 }
1455
1456 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1457 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1458 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1459 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1460 ==eHAL_STATUS_FAILURE)
1461 {
1462 hddLog(LOGE,
1463 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001464 ret = -EINVAL;
1465 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 }
1467
1468 // Added for ProResp IE
1469 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1470 {
1471 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1472 u8 probe_rsp_ie_len[3] = {0};
1473 u8 counter = 0;
1474 /* Check Probe Resp Length if it is greater then 255 then Store
1475 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1476 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1477 Store More then 255 bytes into One Variable.
1478 */
1479 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1480 {
1481 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1482 {
1483 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1484 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1485 }
1486 else
1487 {
1488 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1489 rem_probe_resp_ie_len = 0;
1490 }
1491 }
1492
1493 rem_probe_resp_ie_len = 0;
1494
1495 if (probe_rsp_ie_len[0] > 0)
1496 {
1497 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1498 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1499 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1500 probe_rsp_ie_len[0], NULL,
1501 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1502 {
1503 hddLog(LOGE,
1504 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001505 ret = -EINVAL;
1506 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 }
1508 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1509 }
1510
1511 if (probe_rsp_ie_len[1] > 0)
1512 {
1513 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1514 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1515 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1516 probe_rsp_ie_len[1], NULL,
1517 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1518 {
1519 hddLog(LOGE,
1520 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001521 ret = -EINVAL;
1522 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 }
1524 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1525 }
1526
1527 if (probe_rsp_ie_len[2] > 0)
1528 {
1529 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1530 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1531 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1532 probe_rsp_ie_len[2], NULL,
1533 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1534 {
1535 hddLog(LOGE,
1536 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001537 ret = -EINVAL;
1538 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 }
1540 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1541 }
1542
1543 if (probe_rsp_ie_len[1] == 0 )
1544 {
1545 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1546 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1547 eANI_BOOLEAN_FALSE) )
1548 {
1549 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001550 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001551 }
1552 }
1553
1554 if (probe_rsp_ie_len[2] == 0 )
1555 {
1556 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1557 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1558 eANI_BOOLEAN_FALSE) )
1559 {
1560 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001561 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001562 }
1563 }
1564
1565 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1566 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1567 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1568 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1569 == eHAL_STATUS_FAILURE)
1570 {
1571 hddLog(LOGE,
1572 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001573 ret = -EINVAL;
1574 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 }
1576 }
1577 else
1578 {
1579 // Reset WNI_CFG_PROBE_RSP Flags
1580 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1581
1582 hddLog(VOS_TRACE_LEVEL_INFO,
1583 "%s: No Probe Response IE received in set beacon",
1584 __func__);
1585 }
1586
1587 // Added for AssocResp IE
1588 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1589 {
1590 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1591 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1592 params->assocresp_ies_len, NULL,
1593 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1594 {
1595 hddLog(LOGE,
1596 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001597 ret = -EINVAL;
1598 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 }
1600
1601 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1602 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1603 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1604 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1605 == eHAL_STATUS_FAILURE)
1606 {
1607 hddLog(LOGE,
1608 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001609 ret = -EINVAL;
1610 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 }
1612 }
1613 else
1614 {
1615 hddLog(VOS_TRACE_LEVEL_INFO,
1616 "%s: No Assoc Response IE received in set beacon",
1617 __func__);
1618
1619 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1620 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1621 eANI_BOOLEAN_FALSE) )
1622 {
1623 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001624 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001625 }
1626 }
1627
Jeff Johnsone7245742012-09-05 17:12:55 -07001628done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301630 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001631}
Jeff Johnson295189b2012-06-20 16:38:30 -07001632
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301633/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 * FUNCTION: wlan_hdd_validate_operation_channel
1635 * called by wlan_hdd_cfg80211_start_bss() and
1636 * wlan_hdd_cfg80211_set_channel()
1637 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301638 * channel list.
1639 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001640VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001641{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301642
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 v_U32_t num_ch = 0;
1644 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1645 u32 indx = 0;
1646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301647 v_U8_t fValidChannel = FALSE, count = 0;
1648 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301649
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1651
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301652 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301654 /* Validate the channel */
1655 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301657 if ( channel == rfChannels[count].channelNum )
1658 {
1659 fValidChannel = TRUE;
1660 break;
1661 }
1662 }
1663 if (fValidChannel != TRUE)
1664 {
1665 hddLog(VOS_TRACE_LEVEL_ERROR,
1666 "%s: Invalid Channel [%d]", __func__, channel);
1667 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 }
1669 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301670 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301672 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1673 valid_ch, &num_ch))
1674 {
1675 hddLog(VOS_TRACE_LEVEL_ERROR,
1676 "%s: failed to get valid channel list", __func__);
1677 return VOS_STATUS_E_FAILURE;
1678 }
1679 for (indx = 0; indx < num_ch; indx++)
1680 {
1681 if (channel == valid_ch[indx])
1682 {
1683 break;
1684 }
1685 }
1686
1687 if (indx >= num_ch)
1688 {
1689 hddLog(VOS_TRACE_LEVEL_ERROR,
1690 "%s: Invalid Channel [%d]", __func__, channel);
1691 return VOS_STATUS_E_FAILURE;
1692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001693 }
1694 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301695
Jeff Johnson295189b2012-06-20 16:38:30 -07001696}
1697
Viral Modi3a32cc52013-02-08 11:14:52 -08001698/**
1699 * FUNCTION: wlan_hdd_cfg80211_set_channel
1700 * This function is used to set the channel number
1701 */
1702static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1703 struct ieee80211_channel *chan,
1704 enum nl80211_channel_type channel_type
1705 )
1706{
1707 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001708 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001709 hdd_adapter_t *pAdapter = NULL;
1710 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301711 hdd_context_t *pHddCtx;
1712 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001713
1714 ENTER();
1715
1716 if( NULL == dev )
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001719 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001720 return -ENODEV;
1721 }
1722 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1723
1724 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001725 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001726 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301727
1728 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1729 status = wlan_hdd_validate_context(pHddCtx);
1730
1731 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001732 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1734 "%s: HDD context is not valid", __func__);
1735 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001736 }
1737
1738 /*
1739 * Do freq to chan conversion
1740 * TODO: for 11a
1741 */
1742
1743 channel = ieee80211_frequency_to_channel(freq);
1744
1745 /* Check freq range */
1746 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1747 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001750 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001751 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1752 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1753 return -EINVAL;
1754 }
1755
1756 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1757
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301758 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1759 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001760 {
1761 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1762 {
1763 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001764 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001765 return -EINVAL;
1766 }
1767 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1768 "%s: set channel to [%d] for device mode =%d",
1769 __func__, channel,pAdapter->device_mode);
1770 }
1771 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001772 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001773 )
1774 {
1775 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1776 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1777 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1778
1779 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1780 {
1781 /* Link is up then return cant set channel*/
1782 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001783 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001784 return -EINVAL;
1785 }
1786
1787 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1788 pHddStaCtx->conn_info.operationChannel = channel;
1789 pRoamProfile->ChannelInfo.ChannelList =
1790 &pHddStaCtx->conn_info.operationChannel;
1791 }
1792 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001793 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001794 )
1795 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301796 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1797 {
1798 if(VOS_STATUS_SUCCESS !=
1799 wlan_hdd_validate_operation_channel(pAdapter,channel))
1800 {
1801 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001802 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301803 return -EINVAL;
1804 }
1805 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1806 }
1807 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001808 {
1809 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1810
1811 /* If auto channel selection is configured as enable/ 1 then ignore
1812 channel set by supplicant
1813 */
1814 if ( cfg_param->apAutoChannelSelection )
1815 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301816 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1817 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001818 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1819 "%s: set channel to auto channel (0) for device mode =%d",
1820 __func__, pAdapter->device_mode);
1821 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301822 else
1823 {
1824 if(VOS_STATUS_SUCCESS !=
1825 wlan_hdd_validate_operation_channel(pAdapter,channel))
1826 {
1827 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001828 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301829 return -EINVAL;
1830 }
1831 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1832 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001833 }
1834 }
1835 else
1836 {
1837 hddLog(VOS_TRACE_LEVEL_FATAL,
1838 "%s: Invalid device mode failed to set valid channel", __func__);
1839 return -EINVAL;
1840 }
1841 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301842 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001843}
1844
Jeff Johnson295189b2012-06-20 16:38:30 -07001845#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1846static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1847 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001848#else
1849static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1850 struct cfg80211_beacon_data *params,
1851 const u8 *ssid, size_t ssid_len,
1852 enum nl80211_hidden_ssid hidden_ssid)
1853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001854{
1855 tsap_Config_t *pConfig;
1856 beacon_data_t *pBeacon = NULL;
1857 struct ieee80211_mgmt *pMgmt_frame;
1858 v_U8_t *pIe=NULL;
1859 v_U16_t capab_info;
1860 eCsrAuthType RSNAuthType;
1861 eCsrEncryptionType RSNEncryptType;
1862 eCsrEncryptionType mcRSNEncryptType;
1863 int status = VOS_STATUS_SUCCESS;
1864 tpWLAN_SAPEventCB pSapEventCallback;
1865 hdd_hostapd_state_t *pHostapdState;
1866 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1867 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301868 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001869 struct qc_mac_acl_entry *acl_entry = NULL;
1870 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001871 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001872 v_BOOL_t MFPCapable;
1873 v_BOOL_t MFPRequired;
Jeff Johnson295189b2012-06-20 16:38:30 -07001874
1875 ENTER();
1876
1877 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1878
1879 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1880
1881 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1882
1883 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1884
1885 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1886
1887 //channel is already set in the set_channel Call back
1888 //pConfig->channel = pCommitConfig->channel;
1889
1890 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301891 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1893
1894 pConfig->dtim_period = pBeacon->dtim_period;
1895
Arif Hussain6d2a3322013-11-17 19:50:10 -08001896 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 pConfig->dtim_period);
1898
1899
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001900 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001901 {
1902 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001903 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301904 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1905 {
1906 tANI_BOOLEAN restartNeeded;
1907 pConfig->ieee80211d = 1;
1908 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1909 sme_setRegInfo(hHal, pConfig->countryCode);
1910 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1911 }
1912 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001914 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001915 pConfig->ieee80211d = 1;
1916 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1917 sme_setRegInfo(hHal, pConfig->countryCode);
1918 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001920 else
1921 {
1922 pConfig->ieee80211d = 0;
1923 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301924 /*
1925 * If auto channel is configured i.e. channel is 0,
1926 * so skip channel validation.
1927 */
1928 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1929 {
1930 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1931 {
1932 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001933 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301934 return -EINVAL;
1935 }
1936 }
1937 else
1938 {
1939 if(1 != pHddCtx->is_dynamic_channel_range_set)
1940 {
1941 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1942 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1943 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1944 }
1945 pHddCtx->is_dynamic_channel_range_set = 0;
1946 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001948 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 {
1950 pConfig->ieee80211d = 0;
1951 }
1952 pConfig->authType = eSAP_AUTO_SWITCH;
1953
1954 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301955
1956 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1958
1959 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1960
1961 /*Set wps station to configured*/
1962 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1963
1964 if(pIe)
1965 {
1966 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1967 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001968 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 return -EINVAL;
1970 }
1971 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1972 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001973 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 /* Check 15 bit of WPS IE as it contain information for wps state
1975 * WPS state
1976 */
1977 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1978 {
1979 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1980 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1981 {
1982 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1983 }
1984 }
1985 }
1986 else
1987 {
1988 pConfig->wps_state = SAP_WPS_DISABLED;
1989 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301990 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001991
1992 pConfig->RSNWPAReqIELength = 0;
1993 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301994 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 WLAN_EID_RSN);
1996 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301997 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001998 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1999 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2000 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302001 /* The actual processing may eventually be more extensive than
2002 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 * by the app.
2004 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302005 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002006 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2007 &RSNEncryptType,
2008 &mcRSNEncryptType,
2009 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002010 &MFPCapable,
2011 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 pConfig->pRSNWPAReqIE[1]+2,
2013 pConfig->pRSNWPAReqIE );
2014
2015 if( VOS_STATUS_SUCCESS == status )
2016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302017 /* Now copy over all the security attributes you have
2018 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 * */
2020 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2021 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2022 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2023 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302024 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002025 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2027 }
2028 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302029
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2031 pBeacon->tail, pBeacon->tail_len);
2032
2033 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2034 {
2035 if (pConfig->pRSNWPAReqIE)
2036 {
2037 /*Mixed mode WPA/WPA2*/
2038 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2039 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2040 }
2041 else
2042 {
2043 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2044 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2045 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302046 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002047 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2048 &RSNEncryptType,
2049 &mcRSNEncryptType,
2050 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002051 &MFPCapable,
2052 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 pConfig->pRSNWPAReqIE[1]+2,
2054 pConfig->pRSNWPAReqIE );
2055
2056 if( VOS_STATUS_SUCCESS == status )
2057 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302058 /* Now copy over all the security attributes you have
2059 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002060 * */
2061 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2062 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2063 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2064 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302065 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002066 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2068 }
2069 }
2070 }
2071
Jeff Johnson4416a782013-03-25 14:17:50 -07002072 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2073 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2074 return -EINVAL;
2075 }
2076
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2078
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 if (params->ssid != NULL)
2081 {
2082 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2083 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2084 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2085 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2086 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002087#else
2088 if (ssid != NULL)
2089 {
2090 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2091 pConfig->SSIDinfo.ssid.length = ssid_len;
2092 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2093 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2094 }
2095#endif
2096
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302097 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302099
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 /* default value */
2101 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2102 pConfig->num_accept_mac = 0;
2103 pConfig->num_deny_mac = 0;
2104
2105 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2106 pBeacon->tail, pBeacon->tail_len);
2107
2108 /* pIe for black list is following form:
2109 type : 1 byte
2110 length : 1 byte
2111 OUI : 4 bytes
2112 acl type : 1 byte
2113 no of mac addr in black list: 1 byte
2114 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302115 */
2116 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002117 {
2118 pConfig->SapMacaddr_acl = pIe[6];
2119 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002120 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302122 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2123 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2125 for (i = 0; i < pConfig->num_deny_mac; i++)
2126 {
2127 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2128 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 }
2131 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2132 pBeacon->tail, pBeacon->tail_len);
2133
2134 /* pIe for white list is following form:
2135 type : 1 byte
2136 length : 1 byte
2137 OUI : 4 bytes
2138 acl type : 1 byte
2139 no of mac addr in white list: 1 byte
2140 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302141 */
2142 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002143 {
2144 pConfig->SapMacaddr_acl = pIe[6];
2145 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002146 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302148 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2149 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2151 for (i = 0; i < pConfig->num_accept_mac; i++)
2152 {
2153 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2154 acl_entry++;
2155 }
2156 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302157
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2159
Jeff Johnsone7245742012-09-05 17:12:55 -07002160#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002161 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302162 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2163 * 11ac in .ini and 11ac is supported by both host and firmware.
2164 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2165 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002166 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2167 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302168 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002169 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
Kiet Lam0f320422013-11-21 19:29:17 +05302170 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) &&
2171 (sme_IsFeatureSupportedByDriver(DOT11AC)) && (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002172 {
2173 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002174
2175 /* Disable VHT support in 2.4 GHz band */
2176 if (pConfig->channel <= 14 &&
2177 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2178 {
2179 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2180 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002181 }
2182#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302183
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002184 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2185 {
2186 sme_SelectCBMode(hHal,
2187 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2188 pConfig->channel);
2189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 // ht_capab is not what the name conveys,this is used for protection bitmap
2191 pConfig->ht_capab =
2192 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2193
2194 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2195 {
2196 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2197 return -EINVAL;
2198 }
2199
2200 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302201 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2203 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302204 pConfig->obssProtEnabled =
2205 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002206
Chet Lanctot8cecea22014-02-11 19:09:36 -08002207#ifdef WLAN_FEATURE_11W
2208 pConfig->mfpCapable = MFPCapable;
2209 pConfig->mfpRequired = MFPRequired;
2210 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2211 pConfig->mfpCapable, pConfig->mfpRequired);
2212#endif
2213
Arif Hussain6d2a3322013-11-17 19:50:10 -08002214 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002216 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2217 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2218 (int)pConfig->channel);
2219 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2220 pConfig->SapHw_mode, pConfig->privacy,
2221 pConfig->authType);
2222 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2223 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2224 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2225 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002226
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302227 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 {
2229 //Bss already started. just return.
2230 //TODO Probably it should update some beacon params.
2231 hddLog( LOGE, "Bss Already started...Ignore the request");
2232 EXIT();
2233 return 0;
2234 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302235
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 pConfig->persona = pHostapdAdapter->device_mode;
2237
2238 pSapEventCallback = hdd_hostapd_SAPEventCB;
2239 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2240 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2241 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002242 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 return -EINVAL;
2244 }
2245
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302246 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002247 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2248
2249 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302250
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302252 {
2253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002254 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002255 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 VOS_ASSERT(0);
2257 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302258
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 //Succesfully started Bss update the state bit.
2260 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2261
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002262#ifdef WLAN_FEATURE_P2P_DEBUG
2263 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2264 {
2265 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2266 {
2267 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2268 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002269 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002270 }
2271 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2272 {
2273 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2274 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002275 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002276 }
2277 }
2278#endif
2279
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 pHostapdState->bCommit = TRUE;
2281 EXIT();
2282
2283 return 0;
2284}
2285
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002286#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302287static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2288 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 struct beacon_parameters *params)
2290{
2291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302292 hdd_context_t *pHddCtx;
2293 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002294
2295 ENTER();
2296
Arif Hussain6d2a3322013-11-17 19:50:10 -08002297 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302299 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2300 status = wlan_hdd_validate_context(pHddCtx);
2301
2302 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002303 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2305 "%s: HDD context is not valid", __func__);
2306 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002307 }
2308
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302309 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 )
2312 {
2313 beacon_data_t *old,*new;
2314
2315 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302316
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302318 {
2319 hddLog(VOS_TRACE_LEVEL_WARN,
2320 FL("already beacon info added to session(%d)"),
2321 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002324
2325 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2326
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302327 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002328 {
2329 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002330 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002331 return -EINVAL;
2332 }
2333
2334 pAdapter->sessionCtx.ap.beacon = new;
2335
2336 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2337 }
2338
2339 EXIT();
2340 return status;
2341}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302342
2343static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 struct net_device *dev,
2345 struct beacon_parameters *params)
2346{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302348 hdd_context_t *pHddCtx;
2349 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002350
2351 ENTER();
2352
Arif Hussain6d2a3322013-11-17 19:50:10 -08002353 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 __func__,pAdapter->device_mode);
2355
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302356 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2357 status = wlan_hdd_validate_context(pHddCtx);
2358
2359 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2362 "%s: HDD context is not valid", __func__);
2363 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364 }
2365
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302366 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002367 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302368 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002369 {
2370 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302371
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302373
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302375 {
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 FL("session(%d) old and new heads points to NULL"),
2378 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002381
2382 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2383
2384 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302385 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002386 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002387 return -EINVAL;
2388 }
2389
2390 pAdapter->sessionCtx.ap.beacon = new;
2391
2392 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2393 }
2394
2395 EXIT();
2396 return status;
2397}
2398
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002399#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2400
2401#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002402static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2403 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002404#else
2405static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2406 struct net_device *dev)
2407#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002408{
2409 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002410 hdd_context_t *pHddCtx = NULL;
2411 hdd_scaninfo_t *pScanInfo = NULL;
2412 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302413 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002414
2415 ENTER();
2416
2417 if (NULL == pAdapter)
2418 {
2419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002420 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 return -ENODEV;
2422 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002423
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302424 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2425 status = wlan_hdd_validate_context(pHddCtx);
2426
2427 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: HDD context is not valid", __func__);
2431 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002432 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002433
2434 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2435 if (NULL == staAdapter)
2436 {
2437 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2438 if (NULL == staAdapter)
2439 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2441 "%s: HDD adapter context for STA/P2P-CLI is Null",
2442 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002443 }
2444 }
2445
2446 pScanInfo = &pHddCtx->scan_info;
2447
Arif Hussain6d2a3322013-11-17 19:50:10 -08002448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002449 __func__,pAdapter->device_mode);
2450
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002451 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002452 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302453 long ret;
2454
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002455 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302456 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2457 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302458 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002459 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002460 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302461 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002462 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302464 FL("Timeout occurred while waiting for abortscan %ld"),
2465 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002466
2467 if (pHddCtx->isLogpInProgress)
2468 {
2469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2470 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302471
2472 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002473 return -EAGAIN;
2474 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002475 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002476 }
2477 }
2478
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302479 hdd_hostapd_stop(dev);
2480
Jeff Johnson295189b2012-06-20 16:38:30 -07002481 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002483 )
2484 {
2485 beacon_data_t *old;
2486
2487 old = pAdapter->sessionCtx.ap.beacon;
2488
2489 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302490 {
2491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2492 FL("session(%d) beacon data points to NULL"),
2493 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002494 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002496
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002498
2499 mutex_lock(&pHddCtx->sap_lock);
2500 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2501 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002502 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002503 {
2504 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2505
2506 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2507
2508 if (!VOS_IS_STATUS_SUCCESS(status))
2509 {
2510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002511 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 VOS_ASSERT(0);
2513 }
2514 }
2515 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2516 }
2517 mutex_unlock(&pHddCtx->sap_lock);
2518
2519 if(status != VOS_STATUS_SUCCESS)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002522 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 return -EINVAL;
2524 }
2525
Jeff Johnson4416a782013-03-25 14:17:50 -07002526 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2528 ==eHAL_STATUS_FAILURE)
2529 {
2530 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002531 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 }
2533
Jeff Johnson4416a782013-03-25 14:17:50 -07002534 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002535 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2536 eANI_BOOLEAN_FALSE) )
2537 {
2538 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002539 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002540 }
2541
2542 // Reset WNI_CFG_PROBE_RSP Flags
2543 wlan_hdd_reset_prob_rspies(pAdapter);
2544
2545 pAdapter->sessionCtx.ap.beacon = NULL;
2546 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002547#ifdef WLAN_FEATURE_P2P_DEBUG
2548 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2549 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2550 {
2551 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2552 "GO got removed");
2553 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2554 }
2555#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002556 }
2557 EXIT();
2558 return status;
2559}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002560
2561#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2562
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302563static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2564 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002565 struct cfg80211_ap_settings *params)
2566{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302567 hdd_adapter_t *pAdapter;
2568 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302569 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002570
2571 ENTER();
2572
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302573 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002574 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302576 "%s: Device is Null", __func__);
2577 return -ENODEV;
2578 }
2579
2580 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2581 if (NULL == pAdapter)
2582 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302584 "%s: HDD adapter is Null", __func__);
2585 return -ENODEV;
2586 }
2587
2588 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2589 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302591 "%s: HDD adapter magic is invalid", __func__);
2592 return -ENODEV;
2593 }
2594
2595 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302596 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302597
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302598 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302599 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2601 "%s: HDD context is not valid", __func__);
2602 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302603 }
2604
2605 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2606 __func__, pAdapter->device_mode);
2607
2608 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002609 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002610 )
2611 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302612 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002613
2614 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302615
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002616 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302617 {
2618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2619 FL("already beacon info added to session(%d)"),
2620 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002621 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302622 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002623
2624 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2625
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302626 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002627 {
2628 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302629 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002630 return -EINVAL;
2631 }
2632 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002634 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2635#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2636 params->channel, params->channel_type);
2637#else
2638 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2639#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002640#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002641 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2642 params->ssid_len, params->hidden_ssid);
2643 }
2644
2645 EXIT();
2646 return status;
2647}
2648
2649
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302650static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002651 struct net_device *dev,
2652 struct cfg80211_beacon_data *params)
2653{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302655 hdd_context_t *pHddCtx;
2656 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002657
2658 ENTER();
2659
Arif Hussain6d2a3322013-11-17 19:50:10 -08002660 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002661 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302662
2663 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2664 status = wlan_hdd_validate_context(pHddCtx);
2665
2666 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002667 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2669 "%s: HDD context is not valid", __func__);
2670 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002671 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002672
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302673 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002674 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302675 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002676 {
2677 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302678
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002679 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302680
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002681 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302682 {
2683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2684 FL("session(%d) beacon data points to NULL"),
2685 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002686 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302687 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002688
2689 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2690
2691 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302692 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002693 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002694 return -EINVAL;
2695 }
2696
2697 pAdapter->sessionCtx.ap.beacon = new;
2698
2699 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2700 }
2701
2702 EXIT();
2703 return status;
2704}
2705
2706#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2707
Jeff Johnson295189b2012-06-20 16:38:30 -07002708
2709static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2710 struct net_device *dev,
2711 struct bss_parameters *params)
2712{
2713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2714
2715 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302716
Arif Hussain6d2a3322013-11-17 19:50:10 -08002717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002718 __func__,pAdapter->device_mode);
2719
2720 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002721 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302722 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002723 {
2724 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2725 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302726 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002727 {
2728 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002730 }
2731
2732 EXIT();
2733 return 0;
2734}
2735
Kiet Lam10841362013-11-01 11:36:50 +05302736/* FUNCTION: wlan_hdd_change_country_code_cd
2737* to wait for contry code completion
2738*/
2739void* wlan_hdd_change_country_code_cb(void *pAdapter)
2740{
2741 hdd_adapter_t *call_back_pAdapter = pAdapter;
2742 complete(&call_back_pAdapter->change_country_code);
2743 return NULL;
2744}
2745
Jeff Johnson295189b2012-06-20 16:38:30 -07002746/*
2747 * FUNCTION: wlan_hdd_cfg80211_change_iface
2748 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2749 */
2750int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2751 struct net_device *ndev,
2752 enum nl80211_iftype type,
2753 u32 *flags,
2754 struct vif_params *params
2755 )
2756{
2757 struct wireless_dev *wdev;
2758 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002759 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002760 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002761 tCsrRoamProfile *pRoamProfile = NULL;
2762 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302763 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002764 eMib_dot11DesiredBssType connectedBssType;
2765 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302766 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002767
2768 ENTER();
2769
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002770 if (!pAdapter)
2771 {
2772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "%s: Adapter context is null", __func__);
2774 return VOS_STATUS_E_FAILURE;
2775 }
2776
2777 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2778 if (!pHddCtx)
2779 {
2780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: HDD context is null", __func__);
2782 return VOS_STATUS_E_FAILURE;
2783 }
2784
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302785 status = wlan_hdd_validate_context(pHddCtx);
2786
2787 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002788 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2790 "%s: HDD context is not valid", __func__);
2791 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002792 }
2793
2794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2795 __func__, pAdapter->device_mode);
2796
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302797 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002798 wdev = ndev->ieee80211_ptr;
2799
2800#ifdef WLAN_BTAMP_FEATURE
2801 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2802 (NL80211_IFTYPE_ADHOC == type)||
2803 (NL80211_IFTYPE_AP == type)||
2804 (NL80211_IFTYPE_P2P_GO == type))
2805 {
2806 pHddCtx->isAmpAllowed = VOS_FALSE;
2807 // stop AMP traffic
2808 status = WLANBAP_StopAmp();
2809 if(VOS_STATUS_SUCCESS != status )
2810 {
2811 pHddCtx->isAmpAllowed = VOS_TRUE;
2812 hddLog(VOS_TRACE_LEVEL_FATAL,
2813 "%s: Failed to stop AMP", __func__);
2814 return -EINVAL;
2815 }
2816 }
2817#endif //WLAN_BTAMP_FEATURE
2818 /* Reset the current device mode bit mask*/
2819 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2820
2821 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002823 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002824 )
2825 {
2826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002827 if (!pWextState)
2828 {
2829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2830 "%s: pWextState is null", __func__);
2831 return VOS_STATUS_E_FAILURE;
2832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002833 pRoamProfile = &pWextState->roamProfile;
2834 LastBSSType = pRoamProfile->BSSType;
2835
2836 switch (type)
2837 {
2838 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002839 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 hddLog(VOS_TRACE_LEVEL_INFO,
2841 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2842 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002843#ifdef WLAN_FEATURE_11AC
2844 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2845 {
2846 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2847 }
2848#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302849 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002850 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002851 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002852 //Check for sub-string p2p to confirm its a p2p interface
2853 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302854 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002855 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2856 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2857 }
2858 else
2859 {
2860 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002861 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002862 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302863#ifdef FEATURE_WLAN_TDLS
2864 /* The open adapter for the p2p shall skip initializations in
2865 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2866 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2867 * tdls_init when the change_iface sets the device mode to
2868 * WLAN_HDD_P2P_CLIENT.
2869 */
2870
2871 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2872 {
2873 if (0 != wlan_hdd_tdls_init (pAdapter))
2874 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302875 hddLog(VOS_TRACE_LEVEL_ERROR,
2876 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302877 return -EINVAL;
2878 }
2879 }
2880#endif
2881
Jeff Johnson295189b2012-06-20 16:38:30 -07002882 break;
2883 case NL80211_IFTYPE_ADHOC:
2884 hddLog(VOS_TRACE_LEVEL_INFO,
2885 "%s: setting interface Type to ADHOC", __func__);
2886 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2887 pRoamProfile->phyMode =
2888 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002889 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002890 wdev->iftype = type;
2891 break;
2892
2893 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002894 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002895 {
2896 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2897 "%s: setting interface Type to %s", __func__,
2898 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2899
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002900 //Cancel any remain on channel for GO mode
2901 if (NL80211_IFTYPE_P2P_GO == type)
2902 {
2903 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2904 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002905 if (NL80211_IFTYPE_AP == type)
2906 {
2907 /* As Loading WLAN Driver one interface being created for p2p device
2908 * address. This will take one HW STA and the max number of clients
2909 * that can connect to softAP will be reduced by one. so while changing
2910 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2911 * interface as it is not required in SoftAP mode.
2912 */
2913
2914 // Get P2P Adapter
2915 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2916
2917 if (pP2pAdapter)
2918 {
2919 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2920 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2921 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2922 }
2923 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302924#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002925
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302926 /* A Mutex Lock is introduced while changing the mode to
2927 * protect the concurrent access for the Adapters by TDLS
2928 * module.
2929 */
2930 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2931 {
2932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2933 "%s: unable to lock list", __func__);
2934 return -EINVAL;
2935 }
2936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002937 //De-init the adapter.
2938 hdd_stop_adapter( pHddCtx, pAdapter );
2939 hdd_deinit_adapter( pHddCtx, pAdapter );
2940 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002941 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2942 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302943#ifdef FEATURE_WLAN_TDLS
2944 mutex_unlock(&pHddCtx->tdls_lock);
2945#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002946
2947 //Disable BMPS and IMPS if enabled
2948 //before starting Go
2949 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302951 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002952 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2953 {
2954 //Fail to Exit BMPS
2955 VOS_ASSERT(0);
2956 }
2957 }
2958
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002959 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2960 (pConfig->apRandomBssidEnabled))
2961 {
2962 /* To meet Android requirements create a randomized
2963 MAC address of the form 02:1A:11:Fx:xx:xx */
2964 get_random_bytes(&ndev->dev_addr[3], 3);
2965 ndev->dev_addr[0] = 0x02;
2966 ndev->dev_addr[1] = 0x1A;
2967 ndev->dev_addr[2] = 0x11;
2968 ndev->dev_addr[3] |= 0xF0;
2969 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2970 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002971 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2972 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002973 }
2974
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 hdd_set_ap_ops( pAdapter->dev );
2976
Kiet Lam10841362013-11-01 11:36:50 +05302977 /* This is for only SAP mode where users can
2978 * control country through ini.
2979 * P2P GO follows station country code
2980 * acquired during the STA scanning. */
2981 if((NL80211_IFTYPE_AP == type) &&
2982 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
2983 {
2984 int status = 0;
2985 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
2986 "%s: setting country code from INI ", __func__);
2987 init_completion(&pAdapter->change_country_code);
2988 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2989 (void *)(tSmeChangeCountryCallback)
2990 wlan_hdd_change_country_code_cb,
2991 pConfig->apCntryCode, pAdapter,
2992 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05302993 eSIR_FALSE,
2994 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05302995 if (eHAL_STATUS_SUCCESS == status)
2996 {
2997 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302998 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05302999 &pAdapter->change_country_code,
3000 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303001 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303002 {
3003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303004 FL("SME Timed out while setting country code %ld"),
3005 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003006
3007 if (pHddCtx->isLogpInProgress)
3008 {
3009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3010 "%s: LOGP in Progress. Ignore!!!", __func__);
3011 return -EAGAIN;
3012 }
Kiet Lam10841362013-11-01 11:36:50 +05303013 }
3014 }
3015 else
3016 {
3017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003018 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303019 return -EINVAL;
3020 }
3021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003022 status = hdd_init_ap_mode(pAdapter);
3023 if(status != VOS_STATUS_SUCCESS)
3024 {
3025 hddLog(VOS_TRACE_LEVEL_FATAL,
3026 "%s: Error initializing the ap mode", __func__);
3027 return -EINVAL;
3028 }
3029 hdd_set_conparam(1);
3030
Jeff Johnson295189b2012-06-20 16:38:30 -07003031 /*interface type changed update in wiphy structure*/
3032 if(wdev)
3033 {
3034 wdev->iftype = type;
3035 pHddCtx->change_iface = type;
3036 }
3037 else
3038 {
3039 hddLog(VOS_TRACE_LEVEL_ERROR,
3040 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3041 return -EINVAL;
3042 }
3043 goto done;
3044 }
3045
3046 default:
3047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3048 __func__);
3049 return -EOPNOTSUPP;
3050 }
3051 }
3052 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003053 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003054 )
3055 {
3056 switch(type)
3057 {
3058 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003059 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003060 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303061#ifdef FEATURE_WLAN_TDLS
3062
3063 /* A Mutex Lock is introduced while changing the mode to
3064 * protect the concurrent access for the Adapters by TDLS
3065 * module.
3066 */
3067 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
3068 {
3069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3070 "%s: unable to lock list", __func__);
3071 return -EINVAL;
3072 }
3073#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003074 hdd_stop_adapter( pHddCtx, pAdapter );
3075 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003077 //Check for sub-string p2p to confirm its a p2p interface
3078 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003079 {
3080 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3081 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3082 }
3083 else
3084 {
3085 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003086 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 hdd_set_conparam(0);
3089 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003090 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3091 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303092#ifdef FEATURE_WLAN_TDLS
3093 mutex_unlock(&pHddCtx->tdls_lock);
3094#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303095 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 if( VOS_STATUS_SUCCESS != status )
3097 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003098 /* In case of JB, for P2P-GO, only change interface will be called,
3099 * This is the right place to enable back bmps_imps()
3100 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303101 if (pHddCtx->hdd_wlan_suspended)
3102 {
3103 hdd_set_pwrparams(pHddCtx);
3104 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003105 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003106 goto done;
3107 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003110 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3111 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003112 goto done;
3113 default:
3114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3115 __func__);
3116 return -EOPNOTSUPP;
3117
3118 }
3119
3120 }
3121 else
3122 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303123 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3124 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003125 return -EOPNOTSUPP;
3126 }
3127
3128
3129 if(pRoamProfile)
3130 {
3131 if ( LastBSSType != pRoamProfile->BSSType )
3132 {
3133 /*interface type changed update in wiphy structure*/
3134 wdev->iftype = type;
3135
3136 /*the BSS mode changed, We need to issue disconnect
3137 if connected or in IBSS disconnect state*/
3138 if ( hdd_connGetConnectedBssType(
3139 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3140 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3141 {
3142 /*need to issue a disconnect to CSR.*/
3143 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3144 if( eHAL_STATUS_SUCCESS ==
3145 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3146 pAdapter->sessionId,
3147 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3148 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303149 ret = wait_for_completion_interruptible_timeout(
3150 &pAdapter->disconnect_comp_var,
3151 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3152 if (ret <= 0)
3153 {
3154 hddLog(VOS_TRACE_LEVEL_ERROR,
3155 FL("wait on disconnect_comp_var failed %ld"), ret);
3156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 }
3158 }
3159 }
3160 }
3161
3162done:
3163 /*set bitmask based on updated value*/
3164 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003165
3166 /* Only STA mode support TM now
3167 * all other mode, TM feature should be disabled */
3168 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3169 (~VOS_STA & pHddCtx->concurrency_mode) )
3170 {
3171 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3172 }
3173
Jeff Johnson295189b2012-06-20 16:38:30 -07003174#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303175 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003176 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3177 {
3178 //we are ok to do AMP
3179 pHddCtx->isAmpAllowed = VOS_TRUE;
3180 }
3181#endif //WLAN_BTAMP_FEATURE
3182 EXIT();
3183 return 0;
3184}
3185
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003186#ifdef FEATURE_WLAN_TDLS
3187static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3188 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3189{
3190 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3191 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3192 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003193 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303194 long ret;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003195
3196 ENTER();
3197
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303198 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003199 {
3200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3201 "Invalid arguments");
3202 return -EINVAL;
3203 }
Hoonki Lee27511902013-03-14 18:19:06 -07003204
3205 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3206 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3207 {
3208 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3209 "%s: TDLS mode is disabled OR not enabled in FW."
3210 MAC_ADDRESS_STR " Request declined.",
3211 __func__, MAC_ADDR_ARRAY(mac));
3212 return -ENOTSUPP;
3213 }
3214
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003215 if (pHddCtx->isLogpInProgress)
3216 {
3217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3218 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003219 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003220 return -EBUSY;
3221 }
3222
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303223 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003224
3225 if ( NULL == pTdlsPeer ) {
3226 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3227 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3228 __func__, MAC_ADDR_ARRAY(mac), update);
3229 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003230 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003231
3232 /* in add station, we accept existing valid staId if there is */
3233 if ((0 == update) &&
3234 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3235 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003236 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003237 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003238 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003239 " link_status %d. staId %d. add station ignored.",
3240 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3241 return 0;
3242 }
3243 /* in change station, we accept only when staId is valid */
3244 if ((1 == update) &&
3245 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3246 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3247 {
3248 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3249 "%s: " MAC_ADDRESS_STR
3250 " link status %d. staId %d. change station %s.",
3251 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3252 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3253 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003254 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003255
3256 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303257 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003258 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3260 "%s: " MAC_ADDRESS_STR
3261 " TDLS setup is ongoing. Request declined.",
3262 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003263 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003264 }
3265
3266 /* first to check if we reached to maximum supported TDLS peer.
3267 TODO: for now, return -EPERM looks working fine,
3268 but need to check if any other errno fit into this category.*/
3269 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
3270 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3272 "%s: " MAC_ADDRESS_STR
3273 " TDLS Max peer already connected. Request declined.",
3274 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003275 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003276 }
3277 else
3278 {
3279 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303280 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003281 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003282 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3284 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3285 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003286 return -EPERM;
3287 }
3288 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003289 if (0 == update)
3290 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003291
Jeff Johnsond75fe012013-04-06 10:53:06 -07003292 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303293 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003294 {
3295 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3296 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003297 if(StaParams->htcap_present)
3298 {
3299 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3300 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3301 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3302 "ht_capa->extended_capabilities: %0x",
3303 StaParams->HTCap.extendedHtCapInfo);
3304 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003305 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3306 "params->capability: %0x",StaParams->capability);
3307 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003308 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003309 if(StaParams->vhtcap_present)
3310 {
3311 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3312 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3313 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3314 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3315 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003316 {
3317 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003319 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3320 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3321 "[%d]: %x ", i, StaParams->supported_rates[i]);
3322 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003323 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303324 else if ((1 == update) && (NULL == StaParams))
3325 {
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s : update is true, but staParams is NULL. Error!", __func__);
3328 return -EPERM;
3329 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003330
3331 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3332
3333 if (!update)
3334 {
3335 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3336 pAdapter->sessionId, mac);
3337 }
3338 else
3339 {
3340 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3341 pAdapter->sessionId, mac, StaParams);
3342 }
3343
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303344 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003345 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3346
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303347 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303350 "%s: timeout waiting for tdls add station indication %ld",
3351 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003352 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003353 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303354
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003355 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3356 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003358 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003359 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003360 }
3361
3362 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003363
3364error:
3365 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3366 return -EPERM;
3367
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003368}
3369#endif
3370
Jeff Johnson295189b2012-06-20 16:38:30 -07003371static int wlan_hdd_change_station(struct wiphy *wiphy,
3372 struct net_device *dev,
3373 u8 *mac,
3374 struct station_parameters *params)
3375{
3376 VOS_STATUS status = VOS_STATUS_SUCCESS;
3377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303378 hdd_context_t *pHddCtx;
3379 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003381#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003382 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003383 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303384 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003385#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003386 ENTER();
3387
Gopichand Nakkala29149562013-05-10 21:43:41 +05303388 if ((NULL == pAdapter))
3389 {
3390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3391 "invalid adapter ");
3392 return -EINVAL;
3393 }
3394
3395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3396 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3397
3398 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3399 {
3400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3401 "invalid HDD state or HDD station context");
3402 return -EINVAL;
3403 }
3404
3405 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003406 {
3407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3408 "%s:LOGP in Progress. Ignore!!!", __func__);
3409 return -EAGAIN;
3410 }
3411
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3413
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003414 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3415 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003416 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003417 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303419 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003420 WLANTL_STA_AUTHENTICATED);
3421
Gopichand Nakkala29149562013-05-10 21:43:41 +05303422 if (status != VOS_STATUS_SUCCESS)
3423 {
3424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3425 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3426 return -EINVAL;
3427 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003428 }
3429 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003430 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3431 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303432#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003433 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3434 StaParams.capability = params->capability;
3435 StaParams.uapsd_queues = params->uapsd_queues;
3436 StaParams.max_sp = params->max_sp;
3437
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303438 /* Convert (first channel , number of channels) tuple to
3439 * the total list of channels. This goes with the assumption
3440 * that if the first channel is < 14, then the next channels
3441 * are an incremental of 1 else an incremental of 4 till the number
3442 * of channels.
3443 */
3444 if (0 != params->supported_channels_len) {
3445 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3446 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3447 {
3448 int wifi_chan_index;
3449 StaParams.supported_channels[j] = params->supported_channels[i];
3450 wifi_chan_index =
3451 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3452 no_of_channels = params->supported_channels[i+1];
3453 for(k=1; k <= no_of_channels; k++)
3454 {
3455 StaParams.supported_channels[j+1] =
3456 StaParams.supported_channels[j] + wifi_chan_index;
3457 j+=1;
3458 }
3459 }
3460 StaParams.supported_channels_len = j;
3461 }
3462 vos_mem_copy(StaParams.supported_oper_classes,
3463 params->supported_oper_classes,
3464 params->supported_oper_classes_len);
3465 StaParams.supported_oper_classes_len =
3466 params->supported_oper_classes_len;
3467
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003468 if (0 != params->ext_capab_len)
3469 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3470 sizeof(StaParams.extn_capability));
3471
3472 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003473 {
3474 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003475 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003476 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003477
3478 StaParams.supported_rates_len = params->supported_rates_len;
3479
3480 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3481 * The supported_rates array , for all the structures propogating till Add Sta
3482 * to the firmware has to be modified , if the supplicant (ieee80211) is
3483 * modified to send more rates.
3484 */
3485
3486 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3487 */
3488 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3489 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3490
3491 if (0 != StaParams.supported_rates_len) {
3492 int i = 0;
3493 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3494 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003496 "Supported Rates with Length %d", StaParams.supported_rates_len);
3497 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003499 "[%d]: %0x", i, StaParams.supported_rates[i]);
3500 }
3501
3502 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003503 {
3504 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003505 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003506 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003507
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003508 if (0 != params->ext_capab_len ) {
3509 /*Define A Macro : TODO Sunil*/
3510 if ((1<<4) & StaParams.extn_capability[3]) {
3511 isBufSta = 1;
3512 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303513 /* TDLS Channel Switching Support */
3514 if ((1<<6) & StaParams.extn_capability[3]) {
3515 isOffChannelSupported = 1;
3516 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003517 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303518 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3519 &StaParams, isBufSta,
3520 isOffChannelSupported);
3521
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303522 if (VOS_STATUS_SUCCESS != status) {
3523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3524 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3525 return -EINVAL;
3526 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003527 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3528
3529 if (VOS_STATUS_SUCCESS != status) {
3530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3531 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3532 return -EINVAL;
3533 }
3534 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003535#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303536 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003537 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003538 return status;
3539}
3540
3541/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003542 * FUNCTION: wlan_hdd_cfg80211_add_key
3543 * This function is used to initialize the key information
3544 */
3545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003546static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003547 struct net_device *ndev,
3548 u8 key_index, bool pairwise,
3549 const u8 *mac_addr,
3550 struct key_params *params
3551 )
3552#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003553static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003554 struct net_device *ndev,
3555 u8 key_index, const u8 *mac_addr,
3556 struct key_params *params
3557 )
3558#endif
3559{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003561 tCsrRoamSetKey setKey;
3562 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303563 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003564 v_U32_t roamId= 0xFF;
3565 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003566 hdd_hostapd_state_t *pHostapdState;
3567 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003568 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303569 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003570
3571 ENTER();
3572
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303573 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3574 status = wlan_hdd_validate_context(pHddCtx);
3575
3576 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003577 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "%s: HDD context is not valid", __func__);
3580 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003581 }
3582
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3584 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003585
3586 if (CSR_MAX_NUM_KEY <= key_index)
3587 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 key_index);
3590
3591 return -EINVAL;
3592 }
3593
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003594 if (CSR_MAX_KEY_LEN < params->key_len)
3595 {
3596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3597 params->key_len);
3598
3599 return -EINVAL;
3600 }
3601
3602 hddLog(VOS_TRACE_LEVEL_INFO,
3603 "%s: called with key index = %d & key length %d",
3604 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003605
3606 /*extract key idx, key len and key*/
3607 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3608 setKey.keyId = key_index;
3609 setKey.keyLength = params->key_len;
3610 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3611
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003612 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003613 {
3614 case WLAN_CIPHER_SUITE_WEP40:
3615 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3616 break;
3617
3618 case WLAN_CIPHER_SUITE_WEP104:
3619 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3620 break;
3621
3622 case WLAN_CIPHER_SUITE_TKIP:
3623 {
3624 u8 *pKey = &setKey.Key[0];
3625 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3626
3627 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3628
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003629 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003630
3631 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003632 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 |--------------|----------|----------|
3634 <---16bytes---><--8bytes--><--8bytes-->
3635
3636 */
3637 /*Sme expects the 32 bytes key to be in the below order
3638
3639 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003640 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 |--------------|----------|----------|
3642 <---16bytes---><--8bytes--><--8bytes-->
3643 */
3644 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003645 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003646
3647 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003648 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003649
3650 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003651 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003652
3653
3654 break;
3655 }
3656
3657 case WLAN_CIPHER_SUITE_CCMP:
3658 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3659 break;
3660
3661#ifdef FEATURE_WLAN_WAPI
3662 case WLAN_CIPHER_SUITE_SMS4:
3663 {
3664 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3665 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3666 params->key, params->key_len);
3667 return 0;
3668 }
3669#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003670
Jeff Johnson295189b2012-06-20 16:38:30 -07003671#ifdef FEATURE_WLAN_CCX
3672 case WLAN_CIPHER_SUITE_KRK:
3673 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3674 break;
3675#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003676
3677#ifdef WLAN_FEATURE_11W
3678 case WLAN_CIPHER_SUITE_AES_CMAC:
3679 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003680 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003681#endif
3682
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 __func__, params->cipher);
3686 return -EOPNOTSUPP;
3687 }
3688
3689 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3690 __func__, setKey.encType);
3691
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003692 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3694 (!pairwise)
3695#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003696 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003697#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003698 )
3699 {
3700 /* set group key*/
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3702 "%s- %d: setting Broadcast key",
3703 __func__, __LINE__);
3704 setKey.keyDirection = eSIR_RX_ONLY;
3705 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3706 }
3707 else
3708 {
3709 /* set pairwise key*/
3710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3711 "%s- %d: setting pairwise key",
3712 __func__, __LINE__);
3713 setKey.keyDirection = eSIR_TX_RX;
3714 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3715 }
3716 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3717 {
3718 setKey.keyDirection = eSIR_TX_RX;
3719 /*Set the group key*/
3720 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3721 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003722
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003723 if ( 0 != status )
3724 {
3725 hddLog(VOS_TRACE_LEVEL_ERROR,
3726 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3727 return -EINVAL;
3728 }
3729 /*Save the keys here and call sme_RoamSetKey for setting
3730 the PTK after peer joins the IBSS network*/
3731 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3732 &setKey, sizeof(tCsrRoamSetKey));
3733 return status;
3734 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303735 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3736 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3737 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003738 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003739 if( pHostapdState->bssState == BSS_START )
3740 {
c_hpothu7c55da62014-01-23 18:34:02 +05303741 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3742 vos_status = wlan_hdd_check_ula_done(pAdapter);
3743
3744 if ( vos_status != VOS_STATUS_SUCCESS )
3745 {
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3747 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3748 __LINE__, vos_status );
3749
3750 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3751
3752 return -EINVAL;
3753 }
3754
Jeff Johnson295189b2012-06-20 16:38:30 -07003755 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3756
3757 if ( status != eHAL_STATUS_SUCCESS )
3758 {
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3760 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3761 __LINE__, status );
3762 }
3763 }
3764
3765 /* Saving WEP keys */
3766 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3767 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3768 {
3769 //Save the wep key in ap context. Issue setkey after the BSS is started.
3770 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3771 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3772 }
3773 else
3774 {
3775 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003776 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003777 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3778 }
3779 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003780 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3781 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003782 {
3783 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3785
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3787 if (!pairwise)
3788#else
3789 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3790#endif
3791 {
3792 /* set group key*/
3793 if (pHddStaCtx->roam_info.deferKeyComplete)
3794 {
3795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3796 "%s- %d: Perform Set key Complete",
3797 __func__, __LINE__);
3798 hdd_PerformRoamSetKeyComplete(pAdapter);
3799 }
3800 }
3801
Jeff Johnson295189b2012-06-20 16:38:30 -07003802 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3803
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003804 pWextState->roamProfile.Keys.defaultIndex = key_index;
3805
3806
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003807 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003808 params->key, params->key_len);
3809
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303810
Jeff Johnson295189b2012-06-20 16:38:30 -07003811 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3812
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303813 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003814 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303815 __func__, setKey.peerMac[0], setKey.peerMac[1],
3816 setKey.peerMac[2], setKey.peerMac[3],
3817 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003818 setKey.keyDirection);
3819
3820 vos_status = wlan_hdd_check_ula_done(pAdapter);
3821
3822 if ( vos_status != VOS_STATUS_SUCCESS )
3823 {
3824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3825 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3826 __LINE__, vos_status );
3827
3828 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3829
3830 return -EINVAL;
3831
3832 }
3833
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003834#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303835 /* The supplicant may attempt to set the PTK once pre-authentication
3836 is done. Save the key in the UMAC and include it in the ADD BSS
3837 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003838 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303839 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003840 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303841 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3842 "%s: Update PreAuth Key success", __func__);
3843 return 0;
3844 }
3845 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3846 {
3847 hddLog(VOS_TRACE_LEVEL_ERROR,
3848 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303849 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003850 }
3851#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003852
3853 /* issue set key request to SME*/
3854 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3855 pAdapter->sessionId, &setKey, &roamId );
3856
3857 if ( 0 != status )
3858 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303859 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003860 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3861 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3862 return -EINVAL;
3863 }
3864
3865
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303866 /* in case of IBSS as there was no information available about WEP keys during
3867 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003868 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303869 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3870 !( ( IW_AUTH_KEY_MGMT_802_1X
3871 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003872 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3873 )
3874 &&
3875 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3876 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3877 )
3878 )
3879 {
3880 setKey.keyDirection = eSIR_RX_ONLY;
3881 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3882
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303883 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003884 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303885 __func__, setKey.peerMac[0], setKey.peerMac[1],
3886 setKey.peerMac[2], setKey.peerMac[3],
3887 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 setKey.keyDirection);
3889
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303890 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003891 pAdapter->sessionId, &setKey, &roamId );
3892
3893 if ( 0 != status )
3894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303895 hddLog(VOS_TRACE_LEVEL_ERROR,
3896 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003897 __func__, status);
3898 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3899 return -EINVAL;
3900 }
3901 }
3902 }
3903
3904 return 0;
3905}
3906
3907/*
3908 * FUNCTION: wlan_hdd_cfg80211_get_key
3909 * This function is used to get the key information
3910 */
3911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303912static int wlan_hdd_cfg80211_get_key(
3913 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303915 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 const u8 *mac_addr, void *cookie,
3917 void (*callback)(void *cookie, struct key_params*)
3918 )
3919#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303920static int wlan_hdd_cfg80211_get_key(
3921 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 struct net_device *ndev,
3923 u8 key_index, const u8 *mac_addr, void *cookie,
3924 void (*callback)(void *cookie, struct key_params*)
3925 )
3926#endif
3927{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303928 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003929 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3930 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3931 struct key_params params;
3932
3933 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303934
Arif Hussain6d2a3322013-11-17 19:50:10 -08003935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003936 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303937
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 memset(&params, 0, sizeof(params));
3939
3940 if (CSR_MAX_NUM_KEY <= key_index)
3941 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003943 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003945
3946 switch(pRoamProfile->EncryptionType.encryptionType[0])
3947 {
3948 case eCSR_ENCRYPT_TYPE_NONE:
3949 params.cipher = IW_AUTH_CIPHER_NONE;
3950 break;
3951
3952 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3953 case eCSR_ENCRYPT_TYPE_WEP40:
3954 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3955 break;
3956
3957 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3958 case eCSR_ENCRYPT_TYPE_WEP104:
3959 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3960 break;
3961
3962 case eCSR_ENCRYPT_TYPE_TKIP:
3963 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3964 break;
3965
3966 case eCSR_ENCRYPT_TYPE_AES:
3967 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3968 break;
3969
3970 default:
3971 params.cipher = IW_AUTH_CIPHER_NONE;
3972 break;
3973 }
3974
3975 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3976 params.seq_len = 0;
3977 params.seq = NULL;
3978 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3979 callback(cookie, &params);
3980 return 0;
3981}
3982
3983/*
3984 * FUNCTION: wlan_hdd_cfg80211_del_key
3985 * This function is used to delete the key information
3986 */
3987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303988static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003989 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303990 u8 key_index,
3991 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003992 const u8 *mac_addr
3993 )
3994#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303995static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003996 struct net_device *ndev,
3997 u8 key_index,
3998 const u8 *mac_addr
3999 )
4000#endif
4001{
4002 int status = 0;
4003
4004 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304005 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004006 //it is observed that this is invalidating peer
4007 //key index whenever re-key is done. This is affecting data link.
4008 //It should be ok to ignore del_key.
4009#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4011 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004012 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4013 tCsrRoamSetKey setKey;
4014 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304015
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 ENTER();
4017
4018 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4019 __func__,pAdapter->device_mode);
4020
4021 if (CSR_MAX_NUM_KEY <= key_index)
4022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 key_index);
4025
4026 return -EINVAL;
4027 }
4028
4029 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4030 setKey.keyId = key_index;
4031
4032 if (mac_addr)
4033 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4034 else
4035 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4036
4037 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4038
4039 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004040 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041 )
4042 {
4043
4044 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004045 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4046 if( pHostapdState->bssState == BSS_START)
4047 {
4048 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304049
Jeff Johnson295189b2012-06-20 16:38:30 -07004050 if ( status != eHAL_STATUS_SUCCESS )
4051 {
4052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4053 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4054 __LINE__, status );
4055 }
4056 }
4057 }
4058 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304059 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004060 )
4061 {
4062 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4063
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304064 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4065
4066 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004067 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304068 __func__, setKey.peerMac[0], setKey.peerMac[1],
4069 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 if(pAdapter->sessionCtx.station.conn_info.connState ==
4072 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304076
Jeff Johnson295189b2012-06-20 16:38:30 -07004077 if ( 0 != status )
4078 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304079 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004080 "%s: sme_RoamSetKey failure, returned %d",
4081 __func__, status);
4082 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4083 return -EINVAL;
4084 }
4085 }
4086 }
4087#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004088 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 return status;
4090}
4091
4092/*
4093 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4094 * This function is used to set the default tx key index
4095 */
4096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4097static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4098 struct net_device *ndev,
4099 u8 key_index,
4100 bool unicast, bool multicast)
4101#else
4102static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4103 struct net_device *ndev,
4104 u8 key_index)
4105#endif
4106{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304108 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304109 hdd_wext_state_t *pWextState;
4110 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304111 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004112
4113 ENTER();
4114
Gopichand Nakkala29149562013-05-10 21:43:41 +05304115 if ((NULL == pAdapter))
4116 {
4117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4118 "invalid adapter");
4119 return -EINVAL;
4120 }
4121
4122 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4123 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4124
4125 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4126 {
4127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4128 "invalid Wext state or HDD context");
4129 return -EINVAL;
4130 }
4131
Arif Hussain6d2a3322013-11-17 19:50:10 -08004132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304134
Jeff Johnson295189b2012-06-20 16:38:30 -07004135 if (CSR_MAX_NUM_KEY <= key_index)
4136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004138 key_index);
4139
4140 return -EINVAL;
4141 }
4142
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4144 status = wlan_hdd_validate_context(pHddCtx);
4145
4146 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004147 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4149 "%s: HDD context is not valid", __func__);
4150 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004151 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304152
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004154 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304155 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304157 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004158 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304159 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004160 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304162 {
4163 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004164 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304165
Jeff Johnson295189b2012-06-20 16:38:30 -07004166 tCsrRoamSetKey setKey;
4167 v_U32_t roamId= 0xFF;
4168 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169
4170 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172
Jeff Johnson295189b2012-06-20 16:38:30 -07004173 Keys->defaultIndex = (u8)key_index;
4174 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4175 setKey.keyId = key_index;
4176 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304177
4178 vos_mem_copy(&setKey.Key[0],
4179 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181
Gopichand Nakkala29149562013-05-10 21:43:41 +05304182 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304183
4184 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 &pHddStaCtx->conn_info.bssId[0],
4186 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304187
Gopichand Nakkala29149562013-05-10 21:43:41 +05304188 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4189 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4190 eCSR_ENCRYPT_TYPE_WEP104)
4191 {
4192 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4193 even though ap is configured for WEP-40 encryption. In this canse the key length
4194 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4195 type(104) and switching encryption type to 40*/
4196 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4197 eCSR_ENCRYPT_TYPE_WEP40;
4198 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4199 eCSR_ENCRYPT_TYPE_WEP40;
4200 }
4201
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304202 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004203 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304204
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304206 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304208
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 if ( 0 != status )
4210 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304211 hddLog(VOS_TRACE_LEVEL_ERROR,
4212 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 status);
4214 return -EINVAL;
4215 }
4216 }
4217 }
4218
4219 /* In SoftAp mode setting key direction for default mode */
4220 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4221 {
4222 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4223 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4224 (eCSR_ENCRYPT_TYPE_AES !=
4225 pWextState->roamProfile.EncryptionType.encryptionType[0])
4226 )
4227 {
4228 /* Saving key direction for default key index to TX default */
4229 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4230 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4231 }
4232 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304233
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 return status;
4235}
4236
Jeff Johnson295189b2012-06-20 16:38:30 -07004237/*
4238 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4239 * This function is used to inform the BSS details to nl80211 interface.
4240 */
4241static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4242 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4243{
4244 struct net_device *dev = pAdapter->dev;
4245 struct wireless_dev *wdev = dev->ieee80211_ptr;
4246 struct wiphy *wiphy = wdev->wiphy;
4247 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4248 int chan_no;
4249 int ie_length;
4250 const char *ie;
4251 unsigned int freq;
4252 struct ieee80211_channel *chan;
4253 int rssi = 0;
4254 struct cfg80211_bss *bss = NULL;
4255
4256 ENTER();
4257
4258 if( NULL == pBssDesc )
4259 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004260 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004261 return bss;
4262 }
4263
4264 chan_no = pBssDesc->channelId;
4265 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4266 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4267
4268 if( NULL == ie )
4269 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 return bss;
4272 }
4273
4274#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4275 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4276 {
4277 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4278 }
4279 else
4280 {
4281 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4282 }
4283#else
4284 freq = ieee80211_channel_to_frequency(chan_no);
4285#endif
4286
4287 chan = __ieee80211_get_channel(wiphy, freq);
4288
4289 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4290 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4291 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4292 if (bss == NULL)
4293 {
4294 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4295
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304296 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4297 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004298 pBssDesc->capabilityInfo,
4299 pBssDesc->beaconInterval, ie, ie_length,
4300 rssi, GFP_KERNEL ));
4301}
4302 else
4303 {
4304 return bss;
4305 }
4306}
4307
4308
4309
4310/*
4311 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4312 * This function is used to inform the BSS details to nl80211 interface.
4313 */
4314struct cfg80211_bss*
4315wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4316 tSirBssDescription *bss_desc
4317 )
4318{
4319 /*
4320 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4321 already exists in bss data base of cfg80211 for that particular BSS ID.
4322 Using cfg80211_inform_bss_frame to update the bss entry instead of
4323 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4324 now there is no possibility to get the mgmt(probe response) frame from PE,
4325 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4326 cfg80211_inform_bss_frame.
4327 */
4328 struct net_device *dev = pAdapter->dev;
4329 struct wireless_dev *wdev = dev->ieee80211_ptr;
4330 struct wiphy *wiphy = wdev->wiphy;
4331 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004332#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4333 qcom_ie_age *qie_age = NULL;
4334 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4335#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004336 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004337#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004338 const char *ie =
4339 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4340 unsigned int freq;
4341 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304342 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004343 struct cfg80211_bss *bss_status = NULL;
4344 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4345 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004346 hdd_context_t *pHddCtx;
4347 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004348#ifdef WLAN_OPEN_SOURCE
4349 struct timespec ts;
4350#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004351
Wilson Yangf80a0542013-10-07 13:02:37 -07004352 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4353 status = wlan_hdd_validate_context(pHddCtx);
4354
4355 /*bss_update is not allowed during wlan driver loading or unloading*/
4356 if (pHddCtx->isLoadUnloadInProgress)
4357 {
4358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4359 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4360 return NULL;
4361 }
4362
4363
4364 if (0 != status)
4365 {
4366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4367 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004368 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004369 }
4370
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304371 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004372 if (!mgmt)
4373 {
4374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4375 "%s: memory allocation failed ", __func__);
4376 return NULL;
4377 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004378
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004380
4381#ifdef WLAN_OPEN_SOURCE
4382 /* Android does not want the timestamp from the frame.
4383 Instead it wants a monotonic increasing value */
4384 get_monotonic_boottime(&ts);
4385 mgmt->u.probe_resp.timestamp =
4386 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4387#else
4388 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004389 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4390 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004391
4392#endif
4393
Jeff Johnson295189b2012-06-20 16:38:30 -07004394 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4395 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004396
4397#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4398 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4399 /* Assuming this is the last IE, copy at the end */
4400 ie_length -=sizeof(qcom_ie_age);
4401 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4402 qie_age->element_id = QCOM_VENDOR_IE_ID;
4403 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4404 qie_age->oui_1 = QCOM_OUI1;
4405 qie_age->oui_2 = QCOM_OUI2;
4406 qie_age->oui_3 = QCOM_OUI3;
4407 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4408 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4409#endif
4410
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304412 if (bss_desc->fProbeRsp)
4413 {
4414 mgmt->frame_control |=
4415 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4416 }
4417 else
4418 {
4419 mgmt->frame_control |=
4420 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004422
4423#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304424 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004425 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4426 {
4427 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4428 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304429 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4431
4432 {
4433 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4434 }
4435 else
4436 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4438 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 kfree(mgmt);
4440 return NULL;
4441 }
4442#else
4443 freq = ieee80211_channel_to_frequency(chan_no);
4444#endif
4445 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004446 /*when the band is changed on the fly using the GUI, three things are done
4447 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
4448 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4449 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4450 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4451 * and discards the channels correponding to previous band and calls back with zero bss results.
4452 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
4453 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4454 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4455 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4456 * So drop the bss and continue to next bss.
4457 */
4458 if(chan == NULL)
4459 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004461 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004462 return NULL;
4463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304465 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004466 * */
4467 if (( eConnectionState_Associated ==
4468 pAdapter->sessionCtx.station.conn_info.connState ) &&
4469 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4470 pAdapter->sessionCtx.station.conn_info.bssId,
4471 WNI_CFG_BSSID_LEN)))
4472 {
4473 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4474 rssi = (pAdapter->rssi * 100);
4475 }
4476 else
4477 {
4478 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4479 }
4480
Nirav Shah20ac06f2013-12-12 18:14:06 +05304481 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4482 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4483 chan->center_freq, (int)(rssi/100));
4484
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4486 frame_len, rssi, GFP_KERNEL);
4487 kfree(mgmt);
4488 return bss_status;
4489}
4490
4491/*
4492 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4493 * This function is used to update the BSS data base of CFG8011
4494 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304495struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 tCsrRoamInfo *pRoamInfo
4497 )
4498{
4499 tCsrRoamConnectedProfile roamProfile;
4500 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4501 struct cfg80211_bss *bss = NULL;
4502
4503 ENTER();
4504
4505 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4506 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4507
4508 if (NULL != roamProfile.pBssDesc)
4509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304510 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 &roamProfile);
4512
4513 if (NULL == bss)
4514 {
4515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4516 __func__);
4517 }
4518
4519 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4520 }
4521 else
4522 {
4523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4524 __func__);
4525 }
4526 return bss;
4527}
4528
4529/*
4530 * FUNCTION: wlan_hdd_cfg80211_update_bss
4531 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304532static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4533 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004534 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304535{
Jeff Johnson295189b2012-06-20 16:38:30 -07004536 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4537 tCsrScanResultInfo *pScanResult;
4538 eHalStatus status = 0;
4539 tScanResultHandle pResult;
4540 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004541 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004542
4543 ENTER();
4544
Wilson Yangf80a0542013-10-07 13:02:37 -07004545 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4546
4547 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4550 "%s:LOGP in Progress. Ignore!!!",__func__);
4551 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004552 }
4553
Wilson Yangf80a0542013-10-07 13:02:37 -07004554
4555 /*bss_update is not allowed during wlan driver loading or unloading*/
4556 if (pHddCtx->isLoadUnloadInProgress)
4557 {
4558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4559 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4560 return VOS_STATUS_E_PERM;
4561 }
4562
4563
Jeff Johnson295189b2012-06-20 16:38:30 -07004564 /*
4565 * start getting scan results and populate cgf80211 BSS database
4566 */
4567 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4568
4569 /* no scan results */
4570 if (NULL == pResult)
4571 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304572 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4573 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004574 return status;
4575 }
4576
4577 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4578
4579 while (pScanResult)
4580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304581 /*
4582 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4583 * entry already exists in bss data base of cfg80211 for that
4584 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4585 * bss entry instead of cfg80211_inform_bss, But this call expects
4586 * mgmt packet as input. As of now there is no possibility to get
4587 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004588 * ieee80211_mgmt(probe response) and passing to c
4589 * fg80211_inform_bss_frame.
4590 * */
4591
4592 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4593 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304594
Jeff Johnson295189b2012-06-20 16:38:30 -07004595
4596 if (NULL == bss_status)
4597 {
4598 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004599 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004600 }
4601 else
4602 {
Yue Maf49ba872013-08-19 12:04:25 -07004603 cfg80211_put_bss(
4604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4605 wiphy,
4606#endif
4607 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004608 }
4609
4610 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4611 }
4612
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304613 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004614
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304615 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004616}
4617
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004618void
4619hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4620{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304621 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004622 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004623} /****** end hddPrintMacAddr() ******/
4624
4625void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004626hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004627{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304628 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004629 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004630 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4631 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4632 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004633} /****** end hddPrintPmkId() ******/
4634
4635//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4636//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4637
4638//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4639//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4640
4641#define dump_bssid(bssid) \
4642 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004643 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4644 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004645 }
4646
4647#define dump_pmkid(pMac, pmkid) \
4648 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004649 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4650 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004651 }
4652
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004653#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004654/*
4655 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4656 * This function is used to notify the supplicant of a new PMKSA candidate.
4657 */
4658int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304659 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004660 int index, bool preauth )
4661{
Jeff Johnsone7245742012-09-05 17:12:55 -07004662#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004663 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004664 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004665
4666 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004667 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004668
4669 if( NULL == pRoamInfo )
4670 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004671 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004672 return -EINVAL;
4673 }
4674
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004675 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4676 {
4677 dump_bssid(pRoamInfo->bssid);
4678 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004679 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004680 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004681#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304682 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004683}
4684#endif //FEATURE_WLAN_LFR
4685
Yue Maef608272013-04-08 23:09:17 -07004686#ifdef FEATURE_WLAN_LFR_METRICS
4687/*
4688 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4689 * 802.11r/LFR metrics reporting function to report preauth initiation
4690 *
4691 */
4692#define MAX_LFR_METRICS_EVENT_LENGTH 100
4693VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4694 tCsrRoamInfo *pRoamInfo)
4695{
4696 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4697 union iwreq_data wrqu;
4698
4699 ENTER();
4700
4701 if (NULL == pAdapter)
4702 {
4703 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4704 return VOS_STATUS_E_FAILURE;
4705 }
4706
4707 /* create the event */
4708 memset(&wrqu, 0, sizeof(wrqu));
4709 memset(metrics_notification, 0, sizeof(metrics_notification));
4710
4711 wrqu.data.pointer = metrics_notification;
4712 wrqu.data.length = scnprintf(metrics_notification,
4713 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4714 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4715
4716 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4717
4718 EXIT();
4719
4720 return VOS_STATUS_SUCCESS;
4721}
4722
4723/*
4724 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4725 * 802.11r/LFR metrics reporting function to report preauth completion
4726 * or failure
4727 */
4728VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4729 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4730{
4731 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4732 union iwreq_data wrqu;
4733
4734 ENTER();
4735
4736 if (NULL == pAdapter)
4737 {
4738 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4739 return VOS_STATUS_E_FAILURE;
4740 }
4741
4742 /* create the event */
4743 memset(&wrqu, 0, sizeof(wrqu));
4744 memset(metrics_notification, 0, sizeof(metrics_notification));
4745
4746 scnprintf(metrics_notification, sizeof(metrics_notification),
4747 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4748 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4749
4750 if (1 == preauth_status)
4751 strncat(metrics_notification, " TRUE", 5);
4752 else
4753 strncat(metrics_notification, " FALSE", 6);
4754
4755 wrqu.data.pointer = metrics_notification;
4756 wrqu.data.length = strlen(metrics_notification);
4757
4758 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4759
4760 EXIT();
4761
4762 return VOS_STATUS_SUCCESS;
4763}
4764
4765/*
4766 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4767 * 802.11r/LFR metrics reporting function to report handover initiation
4768 *
4769 */
4770VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4771 tCsrRoamInfo *pRoamInfo)
4772{
4773 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4774 union iwreq_data wrqu;
4775
4776 ENTER();
4777
4778 if (NULL == pAdapter)
4779 {
4780 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4781 return VOS_STATUS_E_FAILURE;
4782 }
4783
4784 /* create the event */
4785 memset(&wrqu, 0, sizeof(wrqu));
4786 memset(metrics_notification, 0, sizeof(metrics_notification));
4787
4788 wrqu.data.pointer = metrics_notification;
4789 wrqu.data.length = scnprintf(metrics_notification,
4790 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4791 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4792
4793 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4794
4795 EXIT();
4796
4797 return VOS_STATUS_SUCCESS;
4798}
4799#endif
4800
Jeff Johnson295189b2012-06-20 16:38:30 -07004801/*
4802 * FUNCTION: hdd_cfg80211_scan_done_callback
4803 * scanning callback function, called after finishing scan
4804 *
4805 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304806static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4808{
4809 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304810 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004812 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4813 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004814 struct cfg80211_scan_request *req = NULL;
4815 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304816 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304817 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004818
4819 ENTER();
4820
4821 hddLog(VOS_TRACE_LEVEL_INFO,
4822 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004823 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 __func__, halHandle, pContext, (int) scanId, (int) status);
4825
Kiet Lamac06e2c2013-10-23 16:25:07 +05304826 pScanInfo->mScanPendingCounter = 0;
4827
Jeff Johnson295189b2012-06-20 16:38:30 -07004828 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304829 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004830 &pScanInfo->scan_req_completion_event,
4831 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304832 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004833 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304834 hddLog(VOS_TRACE_LEVEL_ERROR,
4835 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004836 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004837 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004838 }
4839
Yue Maef608272013-04-08 23:09:17 -07004840 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 {
4842 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004843 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 }
4845
4846 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304847 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 {
4849 hddLog(VOS_TRACE_LEVEL_INFO,
4850 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004851 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 (int) scanId);
4853 }
4854
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304855 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 pAdapter);
4857
4858 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304859 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004860
4861
4862 /* If any client wait scan result through WEXT
4863 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004864 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 {
4866 /* The other scan request waiting for current scan finish
4867 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004868 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004869 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004870 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 }
4872 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004873 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004874 {
4875 struct net_device *dev = pAdapter->dev;
4876 union iwreq_data wrqu;
4877 int we_event;
4878 char *msg;
4879
4880 memset(&wrqu, '\0', sizeof(wrqu));
4881 we_event = SIOCGIWSCAN;
4882 msg = NULL;
4883 wireless_send_event(dev, we_event, &wrqu, msg);
4884 }
4885 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004886 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004887
4888 /* Get the Scan Req */
4889 req = pAdapter->request;
4890
4891 if (!req)
4892 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004893 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004894 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004895 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 }
4897
4898 /*
4899 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304900 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 req->n_ssids = 0;
4902 req->n_channels = 0;
4903 req->ie = 0;
4904
Jeff Johnson295189b2012-06-20 16:38:30 -07004905 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004906 /* Scan is no longer pending */
4907 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004908
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004909 /*
4910 * cfg80211_scan_done informing NL80211 about completion
4911 * of scanning
4912 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304913 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
4914 {
4915 aborted = true;
4916 }
4917 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004918 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004919
Jeff Johnsone7245742012-09-05 17:12:55 -07004920allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004921 /* release the wake lock at the end of the scan*/
4922 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004923
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004924 /* Acquire wakelock to handle the case where APP's tries to suspend
4925 * immediatly after the driver gets connect request(i.e after scan)
4926 * from supplicant, this result in app's is suspending and not able
4927 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304928 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004929
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004930#ifdef FEATURE_WLAN_TDLS
4931 wlan_hdd_tdls_scan_done_callback(pAdapter);
4932#endif
4933
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 EXIT();
4935 return 0;
4936}
4937
4938/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004939 * FUNCTION: hdd_isScanAllowed
4940 * Go through each adapter and check if scan allowed
4941 *
4942 */
4943v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4944{
4945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4946 hdd_station_ctx_t *pHddStaCtx = NULL;
4947 hdd_adapter_t *pAdapter = NULL;
4948 VOS_STATUS status = 0;
4949 v_U8_t staId = 0;
4950 v_U8_t *staMac = NULL;
4951
c_hpothu9b781ba2013-12-30 20:57:45 +05304952 if (TRUE == pHddCtx->btCoexModeSet)
4953 {
4954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4955 FL("BTCoex Mode operation in progress, Do not allow scan"));
4956 return VOS_FALSE;
4957 }
4958
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004959 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4960
4961 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4962 {
4963 pAdapter = pAdapterNode->pAdapter;
4964
4965 if( pAdapter )
4966 {
4967 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304968 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004969 __func__, pAdapter->device_mode);
4970 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4971 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4972 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4973 {
4974 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4975 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4976 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4977 {
4978 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4979 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004980 "%s: client " MAC_ADDRESS_STR
4981 " is in the middle of WPS/EAPOL exchange.", __func__,
4982 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004983 return VOS_FALSE;
4984 }
4985 }
4986 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4987 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4988 {
4989 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304991 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004992 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4993 {
4994 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4995
4996 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004997 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
4998 "middle of WPS/EAPOL exchange.", __func__,
4999 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005000 return VOS_FALSE;
5001 }
5002 }
5003 }
5004 }
5005 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5006 pAdapterNode = pNext;
5007 }
5008 hddLog(VOS_TRACE_LEVEL_INFO,
5009 "%s: Scan allowed", __func__);
5010 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305011}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005012
5013/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 * FUNCTION: wlan_hdd_cfg80211_scan
5015 * this scan respond to scan trigger and update cfg80211 scan database
5016 * later, scan dump command can be used to recieve scan results
5017 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005018int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5019#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5020 struct net_device *dev,
5021#endif
5022 struct cfg80211_scan_request *request)
5023{
5024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5025 struct net_device *dev = request->wdev->netdev;
5026#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5029 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305030 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 tCsrScanRequest scanRequest;
5032 tANI_U8 *channelList = NULL, i;
5033 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305034 int status;
5035 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005037
5038 ENTER();
5039
Arif Hussain6d2a3322013-11-17 19:50:10 -08005040 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005041 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305043 status = wlan_hdd_validate_context(pHddCtx);
5044
5045 if (0 != status)
5046 {
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5048 "%s: HDD context is not valid", __func__);
5049 return status;
5050 }
5051
5052 cfg_param = pHddCtx->cfg_ini;
5053 pScanInfo = &pHddCtx->scan_info;
5054
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005055 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005056 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005057 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005058 {
5059 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005060 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5061 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005062 return -EBUSY;
5063 }
5064
Jeff Johnson295189b2012-06-20 16:38:30 -07005065#ifdef WLAN_BTAMP_FEATURE
5066 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005067 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005068 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005069 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 "%s: No scanning when AMP is on", __func__);
5071 return -EOPNOTSUPP;
5072 }
5073#endif
5074 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005075 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005077 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 "%s: Not scanning on device_mode = %d",
5079 __func__, pAdapter->device_mode);
5080 return -EOPNOTSUPP;
5081 }
5082
5083 if (TRUE == pScanInfo->mScanPending)
5084 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305085 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5086 {
5087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5088 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005089 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 }
5091
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005093 //Channel and action frame is pending
5094 //Otherwise Cancel Remain On Channel and allow Scan
5095 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005096 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005097 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005099 return -EBUSY;
5100 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005101#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005102 /* if tdls disagree scan right now, return immediately.
5103 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5104 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5105 */
5106 status = wlan_hdd_tdls_scan_callback (pAdapter,
5107 wiphy,
5108#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5109 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005110#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005111 request);
5112 if(status <= 0)
5113 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305114 if(!status)
5115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5116 "scan rejected %d", __func__, status);
5117 else
5118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5119 __func__, status);
5120
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005121 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005122 }
5123#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005124
Jeff Johnson295189b2012-06-20 16:38:30 -07005125 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5126 {
5127 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005128 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005131 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5132 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305133 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 "%s: MAX TM Level Scan not allowed", __func__);
5135 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305136 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005137 }
5138 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5139
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005140 /* Check if scan is allowed at this point of time.
5141 */
5142 if (!hdd_isScanAllowed(pHddCtx))
5143 {
5144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5145 return -EBUSY;
5146 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305147
Jeff Johnson295189b2012-06-20 16:38:30 -07005148 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5149
5150 if (NULL != request)
5151 {
5152 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305153 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005154
5155 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5156 * Becasue of this, driver is assuming that this is not wildcard scan and so
5157 * is not aging out the scan results.
5158 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005159 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 {
5161 request->n_ssids = 0;
5162 }
5163
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005164 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005165 {
5166 tCsrSSIDInfo *SsidInfo;
5167 int j;
5168 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5169 /* Allocate num_ssid tCsrSSIDInfo structure */
5170 SsidInfo = scanRequest.SSIDs.SSIDList =
5171 ( tCsrSSIDInfo *)vos_mem_malloc(
5172 request->n_ssids*sizeof(tCsrSSIDInfo));
5173
5174 if(NULL == scanRequest.SSIDs.SSIDList)
5175 {
5176 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305177 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 return -ENOMEM;
5179 }
5180
5181 /* copy all the ssid's and their length */
5182 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5183 {
5184 /* get the ssid length */
5185 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5186 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5187 SsidInfo->SSID.length);
5188 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305189 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005190 j, SsidInfo->SSID.ssId);
5191 }
5192 /* set the scan type to active */
5193 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5194 }
5195 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5196 {
5197 /* set the scan type to active */
5198 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5199 }
5200 else
5201 {
5202 /*Set the scan type to default type, in this case it is ACTIVE*/
5203 scanRequest.scanType = pScanInfo->scan_mode;
5204 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305205 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5207 }
5208 else
5209 {
5210 /* set the scan type to active */
5211 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5212 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5213
5214 /* set min and max channel time to zero */
5215 scanRequest.minChnTime = 0;
5216 scanRequest.maxChnTime = 0;
5217 }
5218
5219 /* set BSSType to default type */
5220 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5221
5222 /*TODO: scan the requested channels only*/
5223
5224 /*Right now scanning all the channels */
5225 if( request )
5226 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305227 hddLog(VOS_TRACE_LEVEL_INFO,
5228 "No of Scan Channels: %d", request->n_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07005229 if( request->n_channels )
5230 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305231 char chList [(request->n_channels*5)+1];
5232 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 channelList = vos_mem_malloc( request->n_channels );
5234 if( NULL == channelList )
5235 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305236 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305237 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005238 status = -ENOMEM;
5239 goto free_mem;
5240 }
5241
Nirav Shah20ac06f2013-12-12 18:14:06 +05305242 for( i = 0, len = 0; i < request->n_channels ; i++ )
5243 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005244 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305245 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5246 }
5247
5248 hddLog(VOS_TRACE_LEVEL_INFO,
5249 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005250 }
5251
5252 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5253 scanRequest.ChannelInfo.ChannelList = channelList;
5254
5255 /* set requestType to full scan */
5256 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305257
5258 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005259 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305260 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005261 */
5262
5263 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305264 * and in that case driver shoudnt flush scan results. If
5265 * driver flushes the scan results here and unfortunately if
5266 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005267 * fails which is not desired
5268 */
5269
5270 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5271 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305272 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005273 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5274 pAdapter->sessionId );
5275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005276
5277 if( request->ie_len )
5278 {
5279 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305280 /*TODO: Array needs to be converted to dynamic allocation,
5281 * as multiple ie.s can be sent in cfg80211_scan_request structure
5282 * CR 597966
5283 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005284 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5285 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5286 pScanInfo->scanAddIE.length = request->ie_len;
5287
Agarwal Ashish4f616132013-12-30 23:32:50 +05305288 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005289 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305290 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305292 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5293 {
5294 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5295 memcpy( pwextBuf->roamProfile.addIEScan,
5296 request->ie, request->ie_len);
5297 }
5298 else
5299 {
5300 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5301 "%d", request->ie_len);
5302 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005303
Agarwal Ashish4f616132013-12-30 23:32:50 +05305304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5306 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5307
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5309 request->ie_len);
5310 if (pP2pIe != NULL)
5311 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005312#ifdef WLAN_FEATURE_P2P_DEBUG
5313 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5314 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5315 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5316 {
5317 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5318 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5319 "Go nego completed to Connection is started");
5320 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5321 "for 8way Handshake");
5322 }
5323 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5324 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5325 {
5326 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5327 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5328 "Disconnected state to Connection is started");
5329 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5330 "for 4way Handshake");
5331 }
5332#endif
5333
Jeff Johnsone7245742012-09-05 17:12:55 -07005334 /* no_cck will be set during p2p find to disable 11b rates */
5335 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005336 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 hddLog(VOS_TRACE_LEVEL_INFO,
5338 "%s: This is a P2P Search", __func__);
5339 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005340
Jeff Johnsone7245742012-09-05 17:12:55 -07005341 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5342 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005343 /* set requestType to P2P Discovery */
5344 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005345 }
5346
5347 /*
5348 Skip Dfs Channel in case of P2P Search
5349 if it is set in ini file
5350 */
5351 if(cfg_param->skipDfsChnlInP2pSearch)
5352 {
5353 scanRequest.skipDfsChnlInP2pSearch = 1;
5354 }
5355 else
5356 {
5357 scanRequest.skipDfsChnlInP2pSearch = 0;
5358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005359
Jeff Johnson295189b2012-06-20 16:38:30 -07005360 }
5361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 }
5363 }
5364
5365 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5366
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005367 /* acquire the wakelock to avoid the apps suspend during the scan. To
5368 * address the following issues.
5369 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5370 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5371 * for long time, this result in apps running at full power for long time.
5372 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5373 * be stuck in full power because of resume BMPS
5374 */
5375 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005376
Nirav Shah20ac06f2013-12-12 18:14:06 +05305377 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5378 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5379 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5380 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5381 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5382
Jeff Johnsone7245742012-09-05 17:12:55 -07005383 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005384 pAdapter->sessionId, &scanRequest, &scanId,
5385 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005386
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 if (eHAL_STATUS_SUCCESS != status)
5388 {
5389 hddLog(VOS_TRACE_LEVEL_ERROR,
5390 "%s: sme_ScanRequest returned error %d", __func__, status);
5391 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005392 if(eHAL_STATUS_RESOURCES == status)
5393 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5395 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005396 status = -EBUSY;
5397 } else {
5398 status = -EIO;
5399 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005400 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005401 goto free_mem;
5402 }
5403
5404 pScanInfo->mScanPending = TRUE;
5405 pAdapter->request = request;
5406 pScanInfo->scanId = scanId;
5407
5408 complete(&pScanInfo->scan_req_completion_event);
5409
5410free_mem:
5411 if( scanRequest.SSIDs.SSIDList )
5412 {
5413 vos_mem_free(scanRequest.SSIDs.SSIDList);
5414 }
5415
5416 if( channelList )
5417 vos_mem_free( channelList );
5418
5419 EXIT();
5420
5421 return status;
5422}
5423
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005424
5425void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5426{
5427 v_U8_t iniDot11Mode =
5428 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5429 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5430
5431 switch ( iniDot11Mode )
5432 {
5433 case eHDD_DOT11_MODE_AUTO:
5434 case eHDD_DOT11_MODE_11ac:
5435 case eHDD_DOT11_MODE_11ac_ONLY:
5436#ifdef WLAN_FEATURE_11AC
5437 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5438#else
5439 hddDot11Mode = eHDD_DOT11_MODE_11n;
5440#endif
5441 break;
5442 case eHDD_DOT11_MODE_11n:
5443 case eHDD_DOT11_MODE_11n_ONLY:
5444 hddDot11Mode = eHDD_DOT11_MODE_11n;
5445 break;
5446 default:
5447 hddDot11Mode = iniDot11Mode;
5448 break;
5449 }
5450 /* This call decides required channel bonding mode */
5451 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5452 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5453 operationChannel);
5454}
5455
Jeff Johnson295189b2012-06-20 16:38:30 -07005456/*
5457 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305458 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305460int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005461 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005462{
5463 int status = 0;
5464 hdd_wext_state_t *pWextState;
5465 v_U32_t roamId;
5466 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 eCsrAuthType RSNAuthType;
5468
5469 ENTER();
5470
5471 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305472
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5474 {
5475 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5476 return -EINVAL;
5477 }
5478
5479 pRoamProfile = &pWextState->roamProfile;
5480
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305481 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005483 hdd_station_ctx_t *pHddStaCtx;
5484 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005485
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305486 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5488 {
5489 /*QoS not enabled in cfg file*/
5490 pRoamProfile->uapsd_mask = 0;
5491 }
5492 else
5493 {
5494 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305495 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5497 }
5498
5499 pRoamProfile->SSIDs.numOfSSIDs = 1;
5500 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5501 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305502 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5504 ssid, ssid_len);
5505
5506 if (bssid)
5507 {
5508 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5509 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5510 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305511 /* Save BSSID in seperate variable as well, as RoamProfile
5512 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 case of join failure we should send valid BSSID to supplicant
5514 */
5515 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5516 WNI_CFG_BSSID_LEN);
5517 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005518 else
5519 {
5520 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5521 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005522
5523 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5524 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305525 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 /*set gen ie*/
5527 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5528 /*set auth*/
5529 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005531#ifdef FEATURE_WLAN_WAPI
5532 if (pAdapter->wapi_info.nWapiMode)
5533 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005534 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 switch (pAdapter->wapi_info.wapiAuthMode)
5536 {
5537 case WAPI_AUTH_MODE_PSK:
5538 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005539 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 pAdapter->wapi_info.wapiAuthMode);
5541 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5542 break;
5543 }
5544 case WAPI_AUTH_MODE_CERT:
5545 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005546 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005547 pAdapter->wapi_info.wapiAuthMode);
5548 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5549 break;
5550 }
5551 } // End of switch
5552 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5553 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5554 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005555 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 pRoamProfile->AuthType.numEntries = 1;
5557 pRoamProfile->EncryptionType.numEntries = 1;
5558 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5559 pRoamProfile->mcEncryptionType.numEntries = 1;
5560 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5561 }
5562 }
5563#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305564#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305565 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305566 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5567 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5568 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305569 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5570 sizeof (tSirGtkOffloadParams));
5571 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305572 }
5573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 pRoamProfile->csrPersona = pAdapter->device_mode;
5575
Jeff Johnson32d95a32012-09-10 13:15:23 -07005576 if( operatingChannel )
5577 {
5578 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5579 pRoamProfile->ChannelInfo.numOfChannels = 1;
5580 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005581 else
5582 {
5583 pRoamProfile->ChannelInfo.ChannelList = NULL;
5584 pRoamProfile->ChannelInfo.numOfChannels = 0;
5585 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005586 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5587 {
5588 hdd_select_cbmode(pAdapter,operatingChannel);
5589 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005590 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5591 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305592 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005593 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005594 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5595 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305596 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5597 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005598 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5599 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305600
5601 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 pAdapter->sessionId, pRoamProfile, &roamId);
5603
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305604 if ((eHAL_STATUS_SUCCESS != status) &&
5605 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5606 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305607
5608 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5610 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5611 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305612 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005613 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305614 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005615
5616 pRoamProfile->ChannelInfo.ChannelList = NULL;
5617 pRoamProfile->ChannelInfo.numOfChannels = 0;
5618
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 }
5620 else
5621 {
5622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5623 return -EINVAL;
5624 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005625 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 return status;
5627}
5628
5629/*
5630 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5631 * This function is used to set the authentication type (OPEN/SHARED).
5632 *
5633 */
5634static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5635 enum nl80211_auth_type auth_type)
5636{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305637 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5639
5640 ENTER();
5641
5642 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305643 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305646 hddLog(VOS_TRACE_LEVEL_INFO,
5647 "%s: set authentication type to AUTOSWITCH", __func__);
5648 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5649 break;
5650
5651 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005652#ifdef WLAN_FEATURE_VOWIFI_11R
5653 case NL80211_AUTHTYPE_FT:
5654#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 "%s: set authentication type to OPEN", __func__);
5657 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5658 break;
5659
5660 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305661 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005662 "%s: set authentication type to SHARED", __func__);
5663 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5664 break;
5665#ifdef FEATURE_WLAN_CCX
5666 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305667 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 "%s: set authentication type to CCKM WPA", __func__);
5669 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5670 break;
5671#endif
5672
5673
5674 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305675 hddLog(VOS_TRACE_LEVEL_ERROR,
5676 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005677 auth_type);
5678 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5679 return -EINVAL;
5680 }
5681
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305682 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005683 pHddStaCtx->conn_info.authType;
5684 return 0;
5685}
5686
5687/*
5688 * FUNCTION: wlan_hdd_set_akm_suite
5689 * This function is used to set the key mgmt type(PSK/8021x).
5690 *
5691 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305692static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 u32 key_mgmt
5694 )
5695{
5696 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5697 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305698
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 /*set key mgmt type*/
5700 switch(key_mgmt)
5701 {
5702 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305703#ifdef WLAN_FEATURE_VOWIFI_11R
5704 case WLAN_AKM_SUITE_FT_PSK:
5705#endif
5706 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 __func__);
5708 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5709 break;
5710
5711 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305712#ifdef WLAN_FEATURE_VOWIFI_11R
5713 case WLAN_AKM_SUITE_FT_8021X:
5714#endif
5715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 __func__);
5717 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5718 break;
5719#ifdef FEATURE_WLAN_CCX
5720#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5721#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5722 case WLAN_AKM_SUITE_CCKM:
5723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5724 __func__);
5725 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5726 break;
5727#endif
5728
5729 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 __func__, key_mgmt);
5732 return -EINVAL;
5733
5734 }
5735 return 0;
5736}
5737
5738/*
5739 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305740 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 * (NONE/WEP40/WEP104/TKIP/CCMP).
5742 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305743static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5744 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 bool ucast
5746 )
5747{
5748 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5751
5752 ENTER();
5753
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 __func__, cipher);
5758 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5759 }
5760 else
5761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305762
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305764 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 {
5766 case IW_AUTH_CIPHER_NONE:
5767 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5768 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305769
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305771 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305773
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305775 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305777
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 case WLAN_CIPHER_SUITE_TKIP:
5779 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5780 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 case WLAN_CIPHER_SUITE_CCMP:
5783 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5784 break;
5785#ifdef FEATURE_WLAN_WAPI
5786 case WLAN_CIPHER_SUITE_SMS4:
5787 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5788 break;
5789#endif
5790
5791#ifdef FEATURE_WLAN_CCX
5792 case WLAN_CIPHER_SUITE_KRK:
5793 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5794 break;
5795#endif
5796 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 __func__, cipher);
5799 return -EOPNOTSUPP;
5800 }
5801 }
5802
5803 if (ucast)
5804 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 __func__, encryptionType);
5807 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5808 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305809 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 encryptionType;
5811 }
5812 else
5813 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 __func__, encryptionType);
5816 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5817 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5818 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5819 }
5820
5821 return 0;
5822}
5823
5824
5825/*
5826 * FUNCTION: wlan_hdd_cfg80211_set_ie
5827 * This function is used to parse WPA/RSN IE's.
5828 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5830 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 size_t ie_len
5832 )
5833{
5834 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5835 u8 *genie = ie;
5836 v_U16_t remLen = ie_len;
5837#ifdef FEATURE_WLAN_WAPI
5838 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5839 u16 *tmp;
5840 v_U16_t akmsuiteCount;
5841 int *akmlist;
5842#endif
5843 ENTER();
5844
5845 /* clear previous assocAddIE */
5846 pWextState->assocAddIE.length = 0;
5847 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5848
5849 while (remLen >= 2)
5850 {
5851 v_U16_t eLen = 0;
5852 v_U8_t elementId;
5853 elementId = *genie++;
5854 eLen = *genie++;
5855 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305856
Arif Hussain6d2a3322013-11-17 19:50:10 -08005857 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305859
5860 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305862 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005863 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 -07005864 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305865 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005866 "%s: Invalid WPA IE", __func__);
5867 return -EINVAL;
5868 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305869 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 {
5871 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305874
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5876 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005877 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5878 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 VOS_ASSERT(0);
5880 return -ENOMEM;
5881 }
5882 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5883 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5884 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5887 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5888 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5889 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305890 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5891 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5893 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5894 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5895 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5896 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5897 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305898 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305899 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 {
5901 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305902 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5906 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005907 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5908 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 VOS_ASSERT(0);
5910 return -ENOMEM;
5911 }
5912 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5913 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5914 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5917 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5918 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005919#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5921 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 /*Consider WFD IE, only for P2P Client */
5923 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5924 {
5925 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305926 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5930 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005931 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5932 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 VOS_ASSERT(0);
5934 return -ENOMEM;
5935 }
5936 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5937 // WPS IE + P2P IE + WFD IE
5938 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5939 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305940
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5942 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5943 }
5944#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005945 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305946 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005947 HS20_OUI_TYPE_SIZE)) )
5948 {
5949 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305950 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005951 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005952
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005953 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5954 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005955 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5956 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005957 VOS_ASSERT(0);
5958 return -ENOMEM;
5959 }
5960 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5961 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005962
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005963 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5964 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5965 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005966
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07005967 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
5968
5969 /* populating as ADDIE in beacon frames */
5970 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5971 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
5972 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
5973 {
5974 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5975 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5976 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5977 {
5978 hddLog(LOGE,
5979 "Coldn't pass "
5980 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
5981 }
5982 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
5983 else
5984 hddLog(LOGE,
5985 "Could not pass on "
5986 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
5987
5988 /* IBSS mode doesn't contain params->proberesp_ies still
5989 beaconIE's need to be populated in probe response frames */
5990 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
5991 {
5992 u16 rem_probe_resp_ie_len = eLen + 2;
5993 u8 probe_rsp_ie_len[3] = {0};
5994 u8 counter = 0;
5995
5996 /* Check Probe Resp Length if it is greater then 255 then
5997 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
5998 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
5999 not able Store More then 255 bytes into One Variable */
6000
6001 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6002 {
6003 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6004 {
6005 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6006 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6007 }
6008 else
6009 {
6010 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6011 rem_probe_resp_ie_len = 0;
6012 }
6013 }
6014
6015 rem_probe_resp_ie_len = 0;
6016
6017 if (probe_rsp_ie_len[0] > 0)
6018 {
6019 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6020 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6021 (tANI_U8*)(genie - 2),
6022 probe_rsp_ie_len[0], NULL,
6023 eANI_BOOLEAN_FALSE)
6024 == eHAL_STATUS_FAILURE)
6025 {
6026 hddLog(LOGE,
6027 "Could not pass"
6028 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6029 }
6030 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6031 }
6032
6033 if (probe_rsp_ie_len[1] > 0)
6034 {
6035 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6036 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6037 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6038 probe_rsp_ie_len[1], NULL,
6039 eANI_BOOLEAN_FALSE)
6040 == eHAL_STATUS_FAILURE)
6041 {
6042 hddLog(LOGE,
6043 "Could not pass"
6044 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6045 }
6046 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6047 }
6048
6049 if (probe_rsp_ie_len[2] > 0)
6050 {
6051 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6052 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6053 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6054 probe_rsp_ie_len[2], NULL,
6055 eANI_BOOLEAN_FALSE)
6056 == eHAL_STATUS_FAILURE)
6057 {
6058 hddLog(LOGE,
6059 "Could not pass"
6060 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6061 }
6062 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6063 }
6064
6065 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6066 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6067 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6068 {
6069 hddLog(LOGE,
6070 "Could not pass"
6071 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6072 }
6073 }
6074 else
6075 {
6076 // Reset WNI_CFG_PROBE_RSP Flags
6077 wlan_hdd_reset_prob_rspies(pAdapter);
6078
6079 hddLog(VOS_TRACE_LEVEL_INFO,
6080 "%s: No Probe Response IE received in set beacon",
6081 __func__);
6082 }
6083 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 break;
6085 case DOT11F_EID_RSN:
6086 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6087 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6088 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6089 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6090 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6091 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006092 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6093 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306094 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006095 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006097 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006099 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6100 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006101 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6102 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006103 VOS_ASSERT(0);
6104 return -ENOMEM;
6105 }
6106 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6107 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006109 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6110 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6111 break;
6112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006113#ifdef FEATURE_WLAN_WAPI
6114 case WLAN_EID_WAPI:
6115 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006116 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 pAdapter->wapi_info.nWapiMode);
6118 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306119 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006120 akmsuiteCount = WPA_GET_LE16(tmp);
6121 tmp = tmp + 1;
6122 akmlist = (int *)(tmp);
6123 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6124 {
6125 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6126 }
6127 else
6128 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006129 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 VOS_ASSERT(0);
6131 return -EINVAL;
6132 }
6133
6134 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6135 {
6136 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006137 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306139 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306141 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006143 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6145 }
6146 break;
6147#endif
6148 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306149 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006151 /* when Unknown IE is received we should break and continue
6152 * to the next IE in the buffer instead we were returning
6153 * so changing this to break */
6154 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 }
6156 genie += eLen;
6157 remLen -= eLen;
6158 }
6159 EXIT();
6160 return 0;
6161}
6162
6163/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306164 * FUNCTION: hdd_isWPAIEPresent
6165 * Parse the received IE to find the WPA IE
6166 *
6167 */
6168static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6169{
6170 v_U8_t eLen = 0;
6171 v_U16_t remLen = ie_len;
6172 v_U8_t elementId = 0;
6173
6174 while (remLen >= 2)
6175 {
6176 elementId = *ie++;
6177 eLen = *ie++;
6178 remLen -= 2;
6179 if (eLen > remLen)
6180 {
6181 hddLog(VOS_TRACE_LEVEL_ERROR,
6182 "%s: IE length is wrong %d", __func__, eLen);
6183 return FALSE;
6184 }
6185 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6186 {
6187 /* OUI - 0x00 0X50 0XF2
6188 WPA Information Element - 0x01
6189 WPA version - 0x01*/
6190 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6191 return TRUE;
6192 }
6193 ie += eLen;
6194 remLen -= eLen;
6195 }
6196 return FALSE;
6197}
6198
6199/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306201 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 * parameters during connect operation.
6203 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306204int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 struct cfg80211_connect_params *req
6206 )
6207{
6208 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306209 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 ENTER();
6211
6212 /*set wpa version*/
6213 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6214
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306215 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306217 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 {
6219 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6220 }
6221 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6222 {
6223 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6224 }
6225 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306226
6227 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 pWextState->wpaVersion);
6229
6230 /*set authentication type*/
6231 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6232
6233 if (0 > status)
6234 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 "%s: failed to set authentication type ", __func__);
6237 return status;
6238 }
6239
6240 /*set key mgmt type*/
6241 if (req->crypto.n_akm_suites)
6242 {
6243 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6244 if (0 > status)
6245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 __func__);
6248 return status;
6249 }
6250 }
6251
6252 /*set pairwise cipher type*/
6253 if (req->crypto.n_ciphers_pairwise)
6254 {
6255 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6256 req->crypto.ciphers_pairwise[0], true);
6257 if (0 > status)
6258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306259 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 "%s: failed to set unicast cipher type", __func__);
6261 return status;
6262 }
6263 }
6264 else
6265 {
6266 /*Reset previous cipher suite to none*/
6267 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6268 if (0 > status)
6269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306270 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 "%s: failed to set unicast cipher type", __func__);
6272 return status;
6273 }
6274 }
6275
6276 /*set group cipher type*/
6277 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6278 false);
6279
6280 if (0 > status)
6281 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 __func__);
6284 return status;
6285 }
6286
Chet Lanctot186b5732013-03-18 10:26:30 -07006287#ifdef WLAN_FEATURE_11W
6288 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6289#endif
6290
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6292 if (req->ie_len)
6293 {
6294 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6295 if ( 0 > status)
6296 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306297 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 __func__);
6299 return status;
6300 }
6301 }
6302
6303 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306304 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 {
6306 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6307 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6308 )
6309 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306310 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 __func__);
6315 return -EOPNOTSUPP;
6316 }
6317 else
6318 {
6319 u8 key_len = req->key_len;
6320 u8 key_idx = req->key_idx;
6321
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306322 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 && (CSR_MAX_NUM_KEY > key_idx)
6324 )
6325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306326 hddLog(VOS_TRACE_LEVEL_INFO,
6327 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 __func__, key_idx, key_len);
6329 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306330 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306332 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 (u8)key_len;
6334 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6335 }
6336 }
6337 }
6338 }
6339
6340 return status;
6341}
6342
6343/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306344 * FUNCTION: wlan_hdd_try_disconnect
6345 * This function is used to disconnect from previous
6346 * connection
6347 */
6348static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6349{
6350 long ret = 0;
6351 hdd_station_ctx_t *pHddStaCtx;
6352 eMib_dot11DesiredBssType connectedBssType;
6353
6354 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6355
6356 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6357
6358 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6359 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6360 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6361 {
6362 /* Issue disconnect to CSR */
6363 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6364 if( eHAL_STATUS_SUCCESS ==
6365 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6366 pAdapter->sessionId,
6367 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6368 {
6369 ret = wait_for_completion_interruptible_timeout(
6370 &pAdapter->disconnect_comp_var,
6371 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6372 if (0 >= ret)
6373 {
6374 hddLog(LOGE, FL("Failed to receive disconnect event"));
6375 return -EALREADY;
6376 }
6377 }
6378 }
6379 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6380 {
6381 ret = wait_for_completion_interruptible_timeout(
6382 &pAdapter->disconnect_comp_var,
6383 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6384 if (0 >= ret)
6385 {
6386 hddLog(LOGE, FL("Failed to receive disconnect event"));
6387 return -EALREADY;
6388 }
6389 }
6390
6391 return 0;
6392}
6393
6394/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 * parameters during connect operation.
6398 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306399static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 struct net_device *ndev,
6401 struct cfg80211_connect_params *req
6402 )
6403{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306404 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006407 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408
6409 ENTER();
6410
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006411 if (!pAdapter)
6412 {
6413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6414 "%s: Adapter context is null", __func__);
6415 return VOS_STATUS_E_FAILURE;
6416 }
6417
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306418 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006419 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006420
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006422 if (!pHddCtx)
6423 {
6424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6425 "%s: HDD context is null", __func__);
6426 return VOS_STATUS_E_FAILURE;
6427 }
6428
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306429 status = wlan_hdd_validate_context(pHddCtx);
6430
6431 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6434 "%s: HDD context is not valid", __func__);
6435 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 }
6437
6438#ifdef WLAN_BTAMP_FEATURE
6439 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306440 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306442 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006444 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 }
6446#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306447
6448 //If Device Mode is Station Concurrent Sessions Exit BMps
6449 //P2P Mode will be taken care in Open/close adapter
6450 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6451 (vos_concurrent_sessions_running()))
6452 {
6453 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6454 }
6455
6456 /*Try disconnecting if already in connected state*/
6457 status = wlan_hdd_try_disconnect(pAdapter);
6458 if ( 0 > status)
6459 {
6460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6461 " connection"));
6462 return -EALREADY;
6463 }
6464
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306466 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006467
6468 if ( 0 > status)
6469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 __func__);
6472 return status;
6473 }
6474
Mohit Khanna765234a2012-09-11 15:08:35 -07006475 if ( req->channel )
6476 {
6477 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6478 req->ssid_len, req->bssid,
6479 req->channel->hw_value);
6480 }
6481 else
6482 {
6483 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306484 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006486
6487 if (0 > status)
6488 {
6489 //ReEnable BMPS if disabled
6490 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6491 (NULL != pHddCtx))
6492 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306493 if (pHddCtx->hdd_wlan_suspended)
6494 {
6495 hdd_set_pwrparams(pHddCtx);
6496 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006497 //ReEnable Bmps and Imps back
6498 hdd_enable_bmps_imps(pHddCtx);
6499 }
6500
6501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6502 return status;
6503 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306504 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 EXIT();
6506 return status;
6507}
6508
6509
6510/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306511 * FUNCTION: wlan_hdd_disconnect
6512 * This function is used to issue a disconnect request to SME
6513 */
6514int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6515{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306516 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306517 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306518 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6519
6520 status = wlan_hdd_validate_context(pHddCtx);
6521
6522 if (0 != status)
6523 {
6524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6525 "%s: HDD context is not valid", __func__);
6526 return status;
6527 }
6528
6529 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306530 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306531 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306532
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306533 /*issue disconnect*/
6534 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6535 pAdapter->sessionId, reason);
6536
6537 if ( 0 != status )
6538 {
6539 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006540 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306541 __func__, (int)status );
6542 return -EINVAL;
6543 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306544 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306545 &pAdapter->disconnect_comp_var,
6546 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306547 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306548 {
6549 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306550 "%s: Failed to disconnect, timed out", __func__);
6551 return -ETIMEDOUT;
6552 }
6553 else if (status == -ERESTARTSYS)
6554 {
6555 hddLog(VOS_TRACE_LEVEL_ERROR,
6556 "%s: Failed to disconnect, wait interrupted", __func__);
6557 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306558 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306559 /*stop tx queues*/
6560 netif_tx_disable(pAdapter->dev);
6561 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306562 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306563}
6564
6565
6566/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 * FUNCTION: wlan_hdd_cfg80211_disconnect
6568 * This function is used to issue a disconnect request to SME
6569 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306570static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 struct net_device *dev,
6572 u16 reason
6573 )
6574{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306575 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6576 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306578 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006580 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306581#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006582 tANI_U8 staIdx;
6583#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306584
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306586
Arif Hussain6d2a3322013-11-17 19:50:10 -08006587 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 __func__,pAdapter->device_mode);
6589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306590 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6591 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006592
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306593 status = wlan_hdd_validate_context(pHddCtx);
6594
6595 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6598 "%s: HDD context is not valid", __func__);
6599 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306601
Jeff Johnson295189b2012-06-20 16:38:30 -07006602 if (NULL != pRoamProfile)
6603 {
6604 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306605 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6606 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306608 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306610 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 switch(reason)
6612 {
6613 case WLAN_REASON_MIC_FAILURE:
6614 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6615 break;
6616
6617 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6618 case WLAN_REASON_DISASSOC_AP_BUSY:
6619 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6620 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6621 break;
6622
6623 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6624 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6625 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6626 break;
6627
6628 case WLAN_REASON_DEAUTH_LEAVING:
6629 default:
6630 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6631 break;
6632 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306633 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6634 pScanInfo = &pHddCtx->scan_info;
6635 if (pScanInfo->mScanPending)
6636 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306637 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306638 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306639 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6640 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006642
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006643#ifdef FEATURE_WLAN_TDLS
6644 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006645 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006646 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006647 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6648 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006649 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006650 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006651 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006652 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006653 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006654 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006655 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006656 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006657 pAdapter->sessionId,
6658 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006659 }
6660 }
6661#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306662 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6663 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006664 {
6665 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006666 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 __func__, (int)status );
6668 return -EINVAL;
6669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006670 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306671 else
6672 {
6673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6674 "called while in %d state", __func__,
6675 pHddStaCtx->conn_info.connState);
6676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 }
6678 else
6679 {
6680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6681 }
6682
6683 return status;
6684}
6685
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306686
Jeff Johnson295189b2012-06-20 16:38:30 -07006687/*
6688 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306689 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 * settings in IBSS mode.
6691 */
6692static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306693 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006694 struct cfg80211_ibss_params *params
6695 )
6696{
6697 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306698 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6700 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306701
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 ENTER();
6703
6704 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006705 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006706
6707 if (params->ie_len && ( NULL != params->ie) )
6708 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006709 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6710 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 {
6712 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6713 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6714 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006715 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006717 tDot11fIEWPA dot11WPAIE;
6718 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006719 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006720
Wilson Yang00256342013-10-10 23:13:38 -07006721 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006722 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6723 params->ie_len, DOT11F_EID_WPA);
6724 if ( NULL != ie )
6725 {
6726 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6727 // Unpack the WPA IE
6728 //Skip past the EID byte and length byte - and four byte WiFi OUI
6729 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6730 &ie[2+4],
6731 ie[1] - 4,
6732 &dot11WPAIE);
6733 /*Extract the multicast cipher, the encType for unicast
6734 cipher for wpa-none is none*/
6735 encryptionType =
6736 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006739
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6741
6742 if (0 > status)
6743 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 __func__);
6746 return status;
6747 }
6748 }
6749
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306750 pWextState->roamProfile.AuthType.authType[0] =
6751 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6753
6754 if (params->privacy)
6755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306756 /* Security enabled IBSS, At this time there is no information available
6757 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306759 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306761 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 *enable privacy bit in beacons */
6763
6764 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6765 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006766 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6767 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6769 pWextState->roamProfile.EncryptionType.numEntries = 1;
6770 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 return status;
6772}
6773
6774/*
6775 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306776 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306778static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 struct net_device *dev,
6780 struct cfg80211_ibss_params *params
6781 )
6782{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6785 tCsrRoamProfile *pRoamProfile;
6786 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006787 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006790
6791 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306792
6793 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006794 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006795
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306796 status = wlan_hdd_validate_context(pHddCtx);
6797
6798 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6801 "%s: HDD context is not valid", __func__);
6802 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 }
6804
6805 if (NULL == pWextState)
6806 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006807 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 __func__);
6809 return -EIO;
6810 }
6811
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306812 /*Try disconnecting if already in connected state*/
6813 status = wlan_hdd_try_disconnect(pAdapter);
6814 if ( 0 > status)
6815 {
6816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6817 " IBSS connection"));
6818 return -EALREADY;
6819 }
6820
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 pRoamProfile = &pWextState->roamProfile;
6822
6823 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306825 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006826 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 return -EINVAL;
6828 }
6829
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006830 /* BSSID is provided by upper layers hence no need to AUTO generate */
6831 if (NULL != params->bssid) {
6832 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6833 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6834 hddLog (VOS_TRACE_LEVEL_ERROR,
6835 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6836 return -EIO;
6837 }
6838 }
krunal sonie9002db2013-11-25 14:24:17 -08006839 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6840 {
6841 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6842 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6843 {
6844 hddLog (VOS_TRACE_LEVEL_ERROR,
6845 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6846 return -EIO;
6847 }
6848 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6849 if (!params->bssid)
6850 {
6851 hddLog (VOS_TRACE_LEVEL_ERROR,
6852 "%s:Failed memory allocation", __func__);
6853 return -EIO;
6854 }
6855 vos_mem_copy((v_U8_t *)params->bssid,
6856 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6857 VOS_MAC_ADDR_SIZE);
6858 alloc_bssid = VOS_TRUE;
6859 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006860
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006862 if (NULL !=
6863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6864 params->chandef.chan)
6865#else
6866 params->channel)
6867#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 {
6869 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006870 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6871 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6872 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6873 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006874
6875 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306876 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006877 ieee80211_frequency_to_channel(
6878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6879 params->chandef.chan->center_freq);
6880#else
6881 params->channel->center_freq);
6882#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006883
6884 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6885 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6888 __func__);
6889 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006890 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006891
6892 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006894 if (channelNum == validChan[indx])
6895 {
6896 break;
6897 }
6898 }
6899 if (indx >= numChans)
6900 {
6901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 __func__, channelNum);
6903 return -EINVAL;
6904 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006905 /* Set the Operational Channel */
6906 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6907 channelNum);
6908 pRoamProfile->ChannelInfo.numOfChannels = 1;
6909 pHddStaCtx->conn_info.operationChannel = channelNum;
6910 pRoamProfile->ChannelInfo.ChannelList =
6911 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 }
6913
6914 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 if (status < 0)
6917 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 __func__);
6920 return status;
6921 }
6922
6923 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006925 params->ssid_len, params->bssid,
6926 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006927
6928 if (0 > status)
6929 {
6930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6931 return status;
6932 }
6933
krunal sonie9002db2013-11-25 14:24:17 -08006934 if (NULL != params->bssid &&
6935 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
6936 alloc_bssid == VOS_TRUE)
6937 {
6938 vos_mem_free(params->bssid);
6939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 return 0;
6941}
6942
6943/*
6944 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306945 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306947static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 struct net_device *dev
6949 )
6950{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306951 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6953 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306954 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6955 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006956
6957 ENTER();
6958
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306959 status = wlan_hdd_validate_context(pHddCtx);
6960
6961 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006962 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6964 "%s: HDD context is not valid", __func__);
6965 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006966 }
6967
Arif Hussain6d2a3322013-11-17 19:50:10 -08006968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006969 if (NULL == pWextState)
6970 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006971 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 __func__);
6973 return -EIO;
6974 }
6975
6976 pRoamProfile = &pWextState->roamProfile;
6977
6978 /* Issue disconnect only if interface type is set to IBSS */
6979 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 __func__);
6983 return -EINVAL;
6984 }
6985
6986 /* Issue Disconnect request */
6987 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6988 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6989 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6990
6991 return 0;
6992}
6993
6994/*
6995 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6996 * This function is used to set the phy parameters
6997 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6998 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306999static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 u32 changed)
7001{
7002 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7003 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307004 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007005
7006 ENTER();
7007
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307008 status = wlan_hdd_validate_context(pHddCtx);
7009
7010 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007011 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7013 "%s: HDD context is not valid", __func__);
7014 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007015 }
7016
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7018 {
7019 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7020 WNI_CFG_RTS_THRESHOLD_STAMAX :
7021 wiphy->rts_threshold;
7022
7023 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307024 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307026 hddLog(VOS_TRACE_LEVEL_ERROR,
7027 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 __func__, rts_threshold);
7029 return -EINVAL;
7030 }
7031
7032 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7033 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307034 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307036 hddLog(VOS_TRACE_LEVEL_ERROR,
7037 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 __func__, rts_threshold);
7039 return -EIO;
7040 }
7041
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307042 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 rts_threshold);
7044 }
7045
7046 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7047 {
7048 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7049 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7050 wiphy->frag_threshold;
7051
7052 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307053 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307055 hddLog(VOS_TRACE_LEVEL_ERROR,
7056 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 frag_threshold);
7058 return -EINVAL;
7059 }
7060
7061 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7062 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307063 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307065 hddLog(VOS_TRACE_LEVEL_ERROR,
7066 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 __func__, frag_threshold);
7068 return -EIO;
7069 }
7070
7071 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7072 frag_threshold);
7073 }
7074
7075 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7076 || (changed & WIPHY_PARAM_RETRY_LONG))
7077 {
7078 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7079 wiphy->retry_short :
7080 wiphy->retry_long;
7081
7082 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7083 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 __func__, retry_value);
7087 return -EINVAL;
7088 }
7089
7090 if (changed & WIPHY_PARAM_RETRY_SHORT)
7091 {
7092 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_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 long 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 long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007102 __func__, retry_value);
7103 }
7104 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7105 {
7106 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7107 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307108 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307110 hddLog(VOS_TRACE_LEVEL_ERROR,
7111 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 __func__, retry_value);
7113 return -EIO;
7114 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307115 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 __func__, retry_value);
7117 }
7118 }
7119
7120 return 0;
7121}
7122
7123/*
7124 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7125 * This function is used to set the txpower
7126 */
7127static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007128#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7129 struct wireless_dev *wdev,
7130#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007131#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307132 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007133#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307134 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007135#endif
7136 int dbm)
7137{
7138 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307139 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7141 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307142 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
7144 ENTER();
7145
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307146 status = wlan_hdd_validate_context(pHddCtx);
7147
7148 if (0 != status)
7149 {
7150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7151 "%s: HDD context is not valid", __func__);
7152 return status;
7153 }
7154
7155 hHal = pHddCtx->hHal;
7156
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307157 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7158 dbm, ccmCfgSetCallback,
7159 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307161 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7163 return -EIO;
7164 }
7165
7166 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7167 dbm);
7168
7169 switch(type)
7170 {
7171 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7172 /* Fall through */
7173 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7174 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7177 __func__);
7178 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 }
7180 break;
7181 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 __func__);
7184 return -EOPNOTSUPP;
7185 break;
7186 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7188 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 return -EIO;
7190 }
7191
7192 return 0;
7193}
7194
7195/*
7196 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7197 * This function is used to read the txpower
7198 */
Yue Maf49ba872013-08-19 12:04:25 -07007199static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7200#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7201 struct wireless_dev *wdev,
7202#endif
7203 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007204{
7205
7206 hdd_adapter_t *pAdapter;
7207 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307208 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007209
Jeff Johnsone7245742012-09-05 17:12:55 -07007210 ENTER();
7211
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307212 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007213
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307214 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007215 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7217 "%s: HDD context is not valid", __func__);
7218 *dbm = 0;
7219 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007220 }
7221
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7223 if (NULL == pAdapter)
7224 {
7225 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7226 return -ENOENT;
7227 }
7228
7229 wlan_hdd_get_classAstats(pAdapter);
7230 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7231
Jeff Johnsone7245742012-09-05 17:12:55 -07007232 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 return 0;
7234}
7235
7236static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7237 u8* mac, struct station_info *sinfo)
7238{
7239 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7240 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7241 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7242 tANI_U8 rate_flags;
7243
7244 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7245 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007246
7247 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7248 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7249 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7250 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7251 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7252 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7253 tANI_U16 maxRate = 0;
7254 tANI_U16 myRate;
7255 tANI_U16 currentRate = 0;
7256 tANI_U8 maxSpeedMCS = 0;
7257 tANI_U8 maxMCSIdx = 0;
7258 tANI_U8 rateFlag = 1;
7259 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007260 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307261 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007262
Leo Chang6f8870f2013-03-26 18:11:36 -07007263#ifdef WLAN_FEATURE_11AC
7264 tANI_U32 vht_mcs_map;
7265 eDataRate11ACMaxMcs vhtMaxMcs;
7266#endif /* WLAN_FEATURE_11AC */
7267
Jeff Johnsone7245742012-09-05 17:12:55 -07007268 ENTER();
7269
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7271 (0 == ssidlen))
7272 {
7273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7274 " Invalid ssidlen, %d", __func__, ssidlen);
7275 /*To keep GUI happy*/
7276 return 0;
7277 }
7278
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307279 status = wlan_hdd_validate_context(pHddCtx);
7280
7281 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007282 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7284 "%s: HDD context is not valid", __func__);
7285 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007286 }
7287
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007288 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7290
Kiet Lam3b17fc82013-09-27 05:24:08 +05307291 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7292 sinfo->filled |= STATION_INFO_SIGNAL;
7293
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 //convert to the UI units of 100kbps
7295 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7296
7297#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007298 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 -07007299 sinfo->signal,
7300 pCfg->reportMaxLinkSpeed,
7301 myRate,
7302 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007303 (int) pCfg->linkSpeedRssiMid,
7304 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007305 (int) rate_flags,
7306 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007307#endif //LINKSPEED_DEBUG_ENABLED
7308
7309 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7310 {
7311 // we do not want to necessarily report the current speed
7312 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7313 {
7314 // report the max possible speed
7315 rssidx = 0;
7316 }
7317 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7318 {
7319 // report the max possible speed with RSSI scaling
7320 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7321 {
7322 // report the max possible speed
7323 rssidx = 0;
7324 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007325 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 {
7327 // report middle speed
7328 rssidx = 1;
7329 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007330 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7331 {
7332 // report middle speed
7333 rssidx = 2;
7334 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 else
7336 {
7337 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007338 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 }
7340 }
7341 else
7342 {
7343 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7344 hddLog(VOS_TRACE_LEVEL_ERROR,
7345 "%s: Invalid value for reportMaxLinkSpeed: %u",
7346 __func__, pCfg->reportMaxLinkSpeed);
7347 rssidx = 0;
7348 }
7349
7350 maxRate = 0;
7351
7352 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307353 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7354 OperationalRates, &ORLeng))
7355 {
7356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7357 /*To keep GUI happy*/
7358 return 0;
7359 }
7360
Jeff Johnson295189b2012-06-20 16:38:30 -07007361 for (i = 0; i < ORLeng; i++)
7362 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007363 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007364 {
7365 /* Validate Rate Set */
7366 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7367 {
7368 currentRate = supported_data_rate[j].supported_rate[rssidx];
7369 break;
7370 }
7371 }
7372 /* Update MAX rate */
7373 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7374 }
7375
7376 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307377 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7378 ExtendedRates, &ERLeng))
7379 {
7380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7381 /*To keep GUI happy*/
7382 return 0;
7383 }
7384
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 for (i = 0; i < ERLeng; i++)
7386 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007387 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 {
7389 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7390 {
7391 currentRate = supported_data_rate[j].supported_rate[rssidx];
7392 break;
7393 }
7394 }
7395 /* Update MAX rate */
7396 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7397 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307398 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307399 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307400 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307401 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307402 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307404 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7405 MCSRates, &MCSLeng))
7406 {
7407 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7408 /*To keep GUI happy*/
7409 return 0;
7410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007412#ifdef WLAN_FEATURE_11AC
7413 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307414 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007416 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307417 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007418 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007419 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007420 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007422 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007424 maxMCSIdx = 7;
7425 }
7426 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7427 {
7428 maxMCSIdx = 8;
7429 }
7430 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7431 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307432 //VHT20 is supporting 0~8
7433 if (rate_flags & eHAL_TX_RATE_VHT20)
7434 maxMCSIdx = 8;
7435 else
7436 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007437 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307438
7439 if (rate_flags & eHAL_TX_RATE_VHT80)
7440 {
7441 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7442 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7443 }
7444 else if (rate_flags & eHAL_TX_RATE_VHT40)
7445 {
7446 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7447 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7448 }
7449 else if (rate_flags & eHAL_TX_RATE_VHT20)
7450 {
7451 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7452 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7453 }
7454
Leo Chang6f8870f2013-03-26 18:11:36 -07007455 maxSpeedMCS = 1;
7456 if (currentRate > maxRate)
7457 {
7458 maxRate = currentRate;
7459 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307460
Leo Chang6f8870f2013-03-26 18:11:36 -07007461 }
7462 else
7463#endif /* WLAN_FEATURE_11AC */
7464 {
7465 if (rate_flags & eHAL_TX_RATE_HT40)
7466 {
7467 rateFlag |= 1;
7468 }
7469 if (rate_flags & eHAL_TX_RATE_SGI)
7470 {
7471 rateFlag |= 2;
7472 }
7473
7474 for (i = 0; i < MCSLeng; i++)
7475 {
7476 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7477 for (j = 0; j < temp; j++)
7478 {
7479 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7480 {
7481 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7482 break;
7483 }
7484 }
7485 if ((j < temp) && (currentRate > maxRate))
7486 {
7487 maxRate = currentRate;
7488 maxSpeedMCS = 1;
7489 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 }
7492 }
7493 }
7494
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307495 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7496 {
7497 maxRate = myRate;
7498 maxSpeedMCS = 1;
7499 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7500 }
7501
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007503 if (((maxRate < myRate) && (0 == rssidx)) ||
7504 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 {
7506 maxRate = myRate;
7507 if (rate_flags & eHAL_TX_RATE_LEGACY)
7508 {
7509 maxSpeedMCS = 0;
7510 }
7511 else
7512 {
7513 maxSpeedMCS = 1;
7514 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7515 }
7516 }
7517
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307518 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 {
7520 sinfo->txrate.legacy = maxRate;
7521#ifdef LINKSPEED_DEBUG_ENABLED
7522 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7523#endif //LINKSPEED_DEBUG_ENABLED
7524 }
7525 else
7526 {
7527 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007528#ifdef WLAN_FEATURE_11AC
7529 sinfo->txrate.nss = 1;
7530 if (rate_flags & eHAL_TX_RATE_VHT80)
7531 {
7532 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307533 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007534 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307535 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007536 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307537 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7538 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7539 }
7540 else if (rate_flags & eHAL_TX_RATE_VHT20)
7541 {
7542 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7543 }
7544#endif /* WLAN_FEATURE_11AC */
7545 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7546 {
7547 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7548 if (rate_flags & eHAL_TX_RATE_HT40)
7549 {
7550 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7551 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 if (rate_flags & eHAL_TX_RATE_SGI)
7554 {
7555 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7556 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307557
Jeff Johnson295189b2012-06-20 16:38:30 -07007558#ifdef LINKSPEED_DEBUG_ENABLED
7559 pr_info("Reporting MCS rate %d flags %x\n",
7560 sinfo->txrate.mcs,
7561 sinfo->txrate.flags );
7562#endif //LINKSPEED_DEBUG_ENABLED
7563 }
7564 }
7565 else
7566 {
7567 // report current rate instead of max rate
7568
7569 if (rate_flags & eHAL_TX_RATE_LEGACY)
7570 {
7571 //provide to the UI in units of 100kbps
7572 sinfo->txrate.legacy = myRate;
7573#ifdef LINKSPEED_DEBUG_ENABLED
7574 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7575#endif //LINKSPEED_DEBUG_ENABLED
7576 }
7577 else
7578 {
7579 //must be MCS
7580 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007581#ifdef WLAN_FEATURE_11AC
7582 sinfo->txrate.nss = 1;
7583 if (rate_flags & eHAL_TX_RATE_VHT80)
7584 {
7585 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7586 }
7587 else
7588#endif /* WLAN_FEATURE_11AC */
7589 {
7590 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007592 if (rate_flags & eHAL_TX_RATE_SGI)
7593 {
7594 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7595 }
7596 if (rate_flags & eHAL_TX_RATE_HT40)
7597 {
7598 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7599 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007600#ifdef WLAN_FEATURE_11AC
7601 else if (rate_flags & eHAL_TX_RATE_VHT80)
7602 {
7603 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7604 }
7605#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007606#ifdef LINKSPEED_DEBUG_ENABLED
7607 pr_info("Reporting actual MCS rate %d flags %x\n",
7608 sinfo->txrate.mcs,
7609 sinfo->txrate.flags );
7610#endif //LINKSPEED_DEBUG_ENABLED
7611 }
7612 }
7613 sinfo->filled |= STATION_INFO_TX_BITRATE;
7614
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007615 sinfo->tx_packets =
7616 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7617 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7618 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7619 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7620
7621 sinfo->tx_retries =
7622 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7623 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7624 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7625 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7626
7627 sinfo->tx_failed =
7628 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7629 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7630 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7631 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7632
7633 sinfo->filled |=
7634 STATION_INFO_TX_PACKETS |
7635 STATION_INFO_TX_RETRIES |
7636 STATION_INFO_TX_FAILED;
7637
7638 EXIT();
7639 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007640}
7641
7642static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007643 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007644{
7645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307646 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307648 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007649
Jeff Johnsone7245742012-09-05 17:12:55 -07007650 ENTER();
7651
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 if (NULL == pAdapter)
7653 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 return -ENODEV;
7656 }
7657
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307660
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307661 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307662 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7664 "%s: HDD context is not valid", __func__);
7665 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307666 }
7667
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307668 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7669 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7670 (pHddCtx->cfg_ini->fhostArpOffload) &&
7671 (eConnectionState_Associated ==
7672 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7673 {
Amar Singhald53568e2013-09-26 11:03:45 -07007674
7675 hddLog(VOS_TRACE_LEVEL_INFO,
7676 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307677 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307678 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7679 {
7680 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007681 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307682 __func__, vos_status);
7683 }
7684 }
7685
Jeff Johnson295189b2012-06-20 16:38:30 -07007686 /**The get power cmd from the supplicant gets updated by the nl only
7687 *on successful execution of the function call
7688 *we are oppositely mapped w.r.t mode in the driver
7689 **/
7690 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7691
Jeff Johnsone7245742012-09-05 17:12:55 -07007692 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 if (VOS_STATUS_E_FAILURE == vos_status)
7694 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7696 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007697 return -EINVAL;
7698 }
7699 return 0;
7700}
7701
7702
7703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7704static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7705 struct net_device *netdev,
7706 u8 key_index)
7707{
Jeff Johnsone7245742012-09-05 17:12:55 -07007708 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 return 0;
7710}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307711#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007712
7713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7714static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7715 struct net_device *dev,
7716 struct ieee80211_txq_params *params)
7717{
Jeff Johnsone7245742012-09-05 17:12:55 -07007718 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007719 return 0;
7720}
7721#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7722static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7723 struct ieee80211_txq_params *params)
7724{
Jeff Johnsone7245742012-09-05 17:12:55 -07007725 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 return 0;
7727}
7728#endif //LINUX_VERSION_CODE
7729
7730static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7731 struct net_device *dev, u8 *mac)
7732{
7733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307734 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007735 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307736 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007737 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007738
Jeff Johnsone7245742012-09-05 17:12:55 -07007739 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307740 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 return -EINVAL;
7744 }
7745
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307746 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7747 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007748
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307749 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007750 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7752 "%s: HDD context is not valid", __func__);
7753 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007754 }
7755
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 )
7759 {
7760 if( NULL == mac )
7761 {
7762 v_U16_t i;
7763 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7764 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007765 if ((pAdapter->aStaInfo[i].isUsed) &&
7766 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 {
7768 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7769 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007770 "%s: Delete STA with MAC::"
7771 MAC_ADDRESS_STR,
7772 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007773 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7774 if (VOS_IS_STATUS_SUCCESS(vos_status))
7775 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 }
7777 }
7778 }
7779 else
7780 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007781
7782 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7783 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7784 {
7785 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007786 "%s: Skip this DEL STA as this is not used::"
7787 MAC_ADDRESS_STR,
7788 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007789 return -ENOENT;
7790 }
7791
7792 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7793 {
7794 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007795 "%s: Skip this DEL STA as deauth is in progress::"
7796 MAC_ADDRESS_STR,
7797 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007798 return -ENOENT;
7799 }
7800
7801 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 hddLog(VOS_TRACE_LEVEL_INFO,
7804 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007805 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007806 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007807 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007808
7809 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7810 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7811 {
7812 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7813 hddLog(VOS_TRACE_LEVEL_INFO,
7814 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007815 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007816 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007817 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007818 return -ENOENT;
7819 }
7820
Jeff Johnson295189b2012-06-20 16:38:30 -07007821 }
7822 }
7823
7824 EXIT();
7825
7826 return 0;
7827}
7828
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007829static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7830 struct net_device *dev, u8 *mac, struct station_parameters *params)
7831{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007832 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007833#ifdef FEATURE_WLAN_TDLS
7834 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007835 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007836 mask = params->sta_flags_mask;
7837
7838 set = params->sta_flags_set;
7839
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007840#ifdef WLAN_FEATURE_TDLS_DEBUG
7841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7842 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7843 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7844#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007845
7846 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7847 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007848 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007849 }
7850 }
7851#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007852 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007853}
7854
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007855
7856#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007857#define MAX_PMKSAIDS_IN_CACHE 8
7858
7859static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7860static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7861
7862
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007863static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007864 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007865{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307866 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7868 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307869 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307870 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007871 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307872 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307873
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007874 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
7875 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07007876
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307877 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307878 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007879 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007881 return -EINVAL;
7882 }
7883
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307884 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7885 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307887 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007888 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7890 "%s: HDD context is not valid", __func__);
7891 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007892 }
7893
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307894 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007895 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7896
Wilson Yang6507c4e2013-10-01 20:11:19 -07007897 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307899 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900 pmksa->bssid, WNI_CFG_BSSID_LEN))
7901 {
7902 /* BSSID matched previous entry. Overwrite it. */
7903 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307904 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007905 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307906 vos_mem_copy(PMKIDCache[j].PMKID,
7907 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007908 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307909 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007910 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007911 dump_bssid(pmksa->bssid);
7912 dump_pmkid(halHandle, pmksa->pmkid);
7913 break;
7914 }
7915 }
7916
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007917 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07007918 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007919
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007920 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307921 {
7922 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07007923 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307924 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007925 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307926 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007927 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307928 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007929 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930 dump_bssid(pmksa->bssid);
7931 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307932 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007933 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07007934 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007935 }
7936
7937
7938 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307939 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007940 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307941 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007942 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007943 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307944 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7945 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007946 PMKIDCacheIndex);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007947 return 0;
7948}
7949
7950
Wilson Yang6507c4e2013-10-01 20:11:19 -07007951
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007952static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007953 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007954{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007955 tANI_U32 j=0;
7956 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7957 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007958 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007959 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08007960 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007961
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007962 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
7963 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007964
7965 /* Validate pAdapter */
7966 if (NULL == pAdapter)
7967 {
7968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
7969 return -EINVAL;
7970 }
7971
7972 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7973 status = wlan_hdd_validate_context(pHddCtx);
7974
7975 if (0 != status)
7976 {
7977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7978 "%s: HDD context is not valid", __func__);
7979 return status;
7980 }
7981
7982 /*Retrieve halHandle*/
7983 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7984
7985 /*in case index is 0,no entry to delete*/
7986 if (0 == PMKIDCacheIndex)
7987 {
7988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7989 __func__);
7990 return -EINVAL;
7991 }
7992
7993 /*find the matching PMKSA entry from j=0 to (index-1),
7994 * and delete the matched one
7995 */
7996 for (j = 0; j<PMKIDCacheIndex; j++)
7997 {
7998 if (vos_mem_compare(PMKIDCache[j].BSSID,
7999 pmksa->bssid,
8000 WNI_CFG_BSSID_LEN))
8001 {
8002 /* BSSID matched entry */
8003 BSSIDMatched = 1;
8004
8005 if (j<PMKIDCacheIndex-1)
8006 {
8007 /*replace the matching entry with the last entry in HDD local cache*/
8008 vos_mem_copy(PMKIDCache[j].BSSID,
8009 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8010 WNI_CFG_BSSID_LEN);
8011 vos_mem_copy(PMKIDCache[j].PMKID,
8012 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8013 CSR_RSN_PMKID_SIZE);
8014 }
8015
8016 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008017 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8018 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8019
8020 /*reduce the PMKID array index*/
8021 PMKIDCacheIndex--;
8022
8023 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008024 if (eHAL_STATUS_SUCCESS !=
8025 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008026 {
8027 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8028 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008029 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008030 }
8031
8032 dump_bssid(pmksa->bssid);
8033 dump_pmkid(halHandle,pmksa->pmkid);
8034
8035 break;
8036 }
8037 }
8038
8039 /* we compare all entries,but cannot find matching entry */
8040 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8041 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008042 hddLog(VOS_TRACE_LEVEL_FATAL,
8043 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8044 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008045 dump_bssid(pmksa->bssid);
8046 dump_pmkid(halHandle, pmksa->pmkid);
8047 return -EINVAL;
8048 }
Wilson Yangef657d32014-01-15 19:19:23 -08008049 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008050}
8051
Wilson Yang6507c4e2013-10-01 20:11:19 -07008052
8053
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008054static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8055{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008056 tANI_U32 j=0;
8057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8058 tHalHandle halHandle;
8059 hdd_context_t *pHddCtx;
8060 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008061 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008062
8063 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8064
8065 /* Validate pAdapter */
8066 if (NULL == pAdapter)
8067 {
8068 hddLog(VOS_TRACE_LEVEL_ERROR,
8069 "%s: Invalid Adapter" ,__func__);
8070 return -EINVAL;
8071 }
8072
8073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8074 status = wlan_hdd_validate_context(pHddCtx);
8075
8076 if (0 != status)
8077 {
8078 hddLog(VOS_TRACE_LEVEL_ERROR,
8079 "%s: HDD context is not valid", __func__);
8080 return status;
8081 }
8082
8083 /*Retrieve halHandle*/
8084 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8085
8086 /*in case index is 0,no entry to delete*/
8087 if (0 == PMKIDCacheIndex)
8088 {
8089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8090 __func__);
8091 return -EINVAL;
8092 }
8093
8094 /*delete all the PMKSA one by one */
8095 for (j = 0; j<PMKIDCacheIndex; j++)
8096 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008097 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008098
8099 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008100 if (eHAL_STATUS_SUCCESS !=
8101 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008102 {
8103 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8104 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008105 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008106 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308107 /*clear the entry in HDD cache 0--index-1 */
8108 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8109 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008110 }
8111
8112 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008113 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008114}
8115#endif
8116
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008117#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308118static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008119 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8120{
8121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8122 hdd_station_ctx_t *pHddStaCtx;
8123
8124 if (NULL == pAdapter)
8125 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008127 return -ENODEV;
8128 }
8129
8130 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8131
8132 // Added for debug on reception of Re-assoc Req.
8133 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8134 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008135 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008136 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008137 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008138 }
8139
8140#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008141 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008142 ftie->ie_len);
8143#endif
8144
8145 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308146 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8147 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008148 ftie->ie_len);
8149 return 0;
8150}
8151#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008152
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308153#ifdef FEATURE_WLAN_SCAN_PNO
8154
8155void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8156 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8157{
8158 int ret;
8159 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8160 hdd_context_t *pHddCtx;
8161
Nirav Shah80830bf2013-12-31 16:35:12 +05308162 ENTER();
8163
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308164 if (NULL == pAdapter)
8165 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308167 "%s: HDD adapter is Null", __func__);
8168 return ;
8169 }
8170
8171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8172 if (NULL == pHddCtx)
8173 {
8174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8175 "%s: HDD context is Null!!!", __func__);
8176 return ;
8177 }
8178
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308179 spin_lock(&pHddCtx->schedScan_lock);
8180 if (TRUE == pHddCtx->isWiphySuspended)
8181 {
8182 pHddCtx->isSchedScanUpdatePending = TRUE;
8183 spin_unlock(&pHddCtx->schedScan_lock);
8184 hddLog(VOS_TRACE_LEVEL_INFO,
8185 "%s: Update cfg80211 scan database after it resume", __func__);
8186 return ;
8187 }
8188 spin_unlock(&pHddCtx->schedScan_lock);
8189
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308190 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8191
8192 if (0 > ret)
8193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8194
8195 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8197 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308198}
8199
8200/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308201 * FUNCTION: wlan_hdd_is_pno_allowed
8202 * To check is there any P2P GO/SAP or P2P Client/STA
8203 * session is active
8204 */
8205static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8206{
8207 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8208 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308209 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308210 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8211 int status = 0;
8212 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8213
8214 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8215 {
8216 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308217 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308218
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308219 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8220 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8221 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8222 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8223 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8224 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308225 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308226 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308227 }
8228 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8229 pAdapterNode = pNext;
8230 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308231 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308232}
8233
8234/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308235 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8236 * NL interface to enable PNO
8237 */
8238static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8239 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8240{
8241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8242 tpSirPNOScanReq pPnoRequest = NULL;
8243 hdd_context_t *pHddCtx;
8244 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308245 v_U32_t i, indx, num_ch, tempInterval;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308246 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8247 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8248 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8249 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308250 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308251
8252 if (NULL == pAdapter)
8253 {
8254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8255 "%s: HDD adapter is Null", __func__);
8256 return -ENODEV;
8257 }
8258
8259 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308260 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308261
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308262 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308263 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8265 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308266 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308267 }
8268
8269 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8270 if (NULL == hHal)
8271 {
8272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8273 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308274 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308275 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308276
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308277 /* The current firmware design for PNO does not consider concurrent
8278 * active sessions.Hence , determine the concurrent active sessions
8279 * and return a failure to the framework on a request for schedule
8280 * scan.
8281 */
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308282 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308283 {
8284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308285 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308286 return -EBUSY;
8287 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308288
8289 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8290 if (NULL == pPnoRequest)
8291 {
8292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8293 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308294 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308295 }
8296
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308297 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308298 pPnoRequest->enable = 1; /*Enable PNO */
8299 pPnoRequest->ucNetworksCount = request->n_match_sets;
8300
8301 if (( !pPnoRequest->ucNetworksCount ) ||
8302 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8303 {
8304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308305 "%s: Network input is not correct %d",
8306 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308307 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308308 goto error;
8309 }
8310
8311 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8312 {
8313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308314 "%s: Incorrect number of channels %d",
8315 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308316 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308317 goto error;
8318 }
8319
8320 /* Framework provides one set of channels(all)
8321 * common for all saved profile */
8322 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8323 channels_allowed, &num_channels_allowed))
8324 {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308327 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308328 goto error;
8329 }
8330 /* Checking each channel against allowed channel list */
8331 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308332 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308333 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308334 char chList [(request->n_channels*5)+1];
8335 int len;
8336 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308337 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308338 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308339 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308340 if (request->channels[i]->hw_value == channels_allowed[indx])
8341 {
8342 valid_ch[num_ch++] = request->channels[i]->hw_value;
8343 len += snprintf(chList+len, 5, "%d ",
8344 request->channels[i]->hw_value);
8345 break ;
8346 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308347 }
8348 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308349 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8350 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308351
8352 /* Filling per profile params */
8353 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8354 {
8355 pPnoRequest->aNetworks[i].ssId.length =
8356 request->match_sets[i].ssid.ssid_len;
8357
8358 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8359 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8360 {
8361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308362 "%s: SSID Len %d is not correct for network %d",
8363 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308364 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308365 goto error;
8366 }
8367
8368 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8369 request->match_sets[i].ssid.ssid,
8370 request->match_sets[i].ssid.ssid_len);
8371 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8372 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8373 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8374
8375 /*Copying list of valid channel into request */
8376 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8377 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8378
8379 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8380 }
8381
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008383 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308384 if ((0 < request->ie_len) && (NULL != request->ie))
8385 {
8386 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8387 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8388 pPnoRequest->us24GProbeTemplateLen);
8389
8390 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8391 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8392 pPnoRequest->us5GProbeTemplateLen);
8393 }
8394
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308395 /* Driver gets only one time interval which is hardcoded in
8396 * supplicant for 10000ms. Taking power consumption into account 6 timers
8397 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8398 * 80,160,320 secs. And number of scan cycle for each timer
8399 * is configurable through INI param gPNOScanTimerRepeatValue.
8400 * If it is set to 0 only one timer will be used and PNO scan cycle
8401 * will be repeated after each interval specified by supplicant
8402 * till PNO is disabled.
8403 */
8404 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8405 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8406 else
8407 pPnoRequest->scanTimers.ucScanTimersCount =
8408 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8409
8410 tempInterval = (request->interval)/1000;
8411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8412 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8413 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8414 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8415 {
8416 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8417 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8418 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8419 tempInterval *= 2;
8420 }
8421 //Repeat last timer until pno disabled.
8422 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8423
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308424 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308425
Nirav Shah80830bf2013-12-31 16:35:12 +05308426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8427 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8428 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8429 pPnoRequest->scanTimers.ucScanTimersCount);
8430
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308431 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8432 pPnoRequest, pAdapter->sessionId,
8433 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8434 if (eHAL_STATUS_SUCCESS != status)
8435 {
8436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308437 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308438 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308439 goto error;
8440 }
8441
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8443 "PNO scanRequest offloaded");
8444
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308445error:
8446 vos_mem_free(pPnoRequest);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308447 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308448}
8449
8450/*
8451 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8452 * NL interface to disable PNO
8453 */
8454static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8455 struct net_device *dev)
8456{
8457 eHalStatus status = eHAL_STATUS_FAILURE;
8458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8459 hdd_context_t *pHddCtx;
8460 tHalHandle hHal;
8461 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308462 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308463
8464 ENTER();
8465
8466 if (NULL == pAdapter)
8467 {
8468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8469 "%s: HDD adapter is Null", __func__);
8470 return -ENODEV;
8471 }
8472
8473 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308474
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308475 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308476 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308478 "%s: HDD context is Null", __func__);
8479 return -ENODEV;
8480 }
8481
8482 /* The return 0 is intentional when isLogpInProgress and
8483 * isLoadUnloadInProgress. We did observe a crash due to a return of
8484 * failure in sched_scan_stop , especially for a case where the unload
8485 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8486 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8487 * success. If it returns a failure , then its next invocation due to the
8488 * clean up of the second interface will have the dev pointer corresponding
8489 * to the first one leading to a crash.
8490 */
8491 if (pHddCtx->isLogpInProgress)
8492 {
8493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8494 "%s: LOGP in Progress. Ignore!!!", __func__);
8495 return ret;
8496 }
8497
8498 if (pHddCtx->isLoadUnloadInProgress)
8499 {
8500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8501 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8502 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308503 }
8504
8505 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8506 if (NULL == hHal)
8507 {
8508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8509 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308510 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308511 }
8512
8513 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8514 if (NULL == pPnoRequest)
8515 {
8516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8517 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308518 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308519 }
8520
8521 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8522 pPnoRequest->enable = 0; /* Disable PNO */
8523 pPnoRequest->ucNetworksCount = 0;
8524
8525 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8526 pAdapter->sessionId,
8527 NULL, pAdapter);
8528 if (eHAL_STATUS_SUCCESS != status)
8529 {
8530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8531 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308532 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308533 }
8534
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8536 "%s: PNO scan disabled", __func__);
8537
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308538 vos_mem_free(pPnoRequest);
8539
8540 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308541 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308542}
8543
8544#endif /*FEATURE_WLAN_SCAN_PNO*/
8545
8546
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008547#ifdef FEATURE_WLAN_TDLS
8548static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8549 u8 *peer, u8 action_code, u8 dialog_token,
8550 u16 status_code, const u8 *buf, size_t len)
8551{
8552
8553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8554 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008555 u8 peerMac[6];
8556 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008557 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008558 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008559 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008560
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008561 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008564 "Invalid arguments");
8565 return -EINVAL;
8566 }
8567
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008568 if (pHddCtx->isLogpInProgress)
8569 {
8570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8571 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008572 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008573 return -EBUSY;
8574 }
8575
Hoonki Lee27511902013-03-14 18:19:06 -07008576 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008577 {
Hoonki Lee27511902013-03-14 18:19:06 -07008578 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8579 "%s: TDLS mode is disabled OR not enabled in FW."
8580 MAC_ADDRESS_STR " action %d declined.",
8581 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008582 return -ENOTSUPP;
8583 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008584
Hoonki Lee27511902013-03-14 18:19:06 -07008585 /* other than teardown frame, other mgmt frames are not sent if disabled */
8586 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8587 {
8588 /* if tdls_mode is disabled to respond to peer's request */
8589 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8590 {
8591 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8592 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008593 " TDLS mode is disabled. action %d declined.",
8594 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008595
8596 return -ENOTSUPP;
8597 }
8598 }
8599
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008600 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8601 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308602 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008603 {
8604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008605 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008606 " TDLS setup is ongoing. action %d declined.",
8607 __func__, MAC_ADDR_ARRAY(peer), action_code);
8608 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008609 }
8610 }
8611
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008612 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8613 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008614 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008615 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008616 {
8617 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8618 we return error code at 'add_station()'. Hence we have this
8619 check again in addtion to add_station().
8620 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008621 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008622 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8624 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008625 " TDLS Max peer already connected. action %d declined.",
8626 __func__, MAC_ADDR_ARRAY(peer), action_code);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308627 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008628 }
8629 else
8630 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008631 /* maximum reached. tweak to send error code to peer and return
8632 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008633 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8635 "%s: " MAC_ADDRESS_STR
8636 " TDLS Max peer already connected send response status %d",
8637 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008638 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008639 /* fall through to send setup resp with failure status
8640 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008641 }
8642 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008643 else
8644 {
8645 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308646 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008647 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008648 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008650 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8651 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008652 return -EPERM;
8653 }
8654 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008655 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008656 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008657
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008658#ifdef WLAN_FEATURE_TDLS_DEBUG
8659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008660 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
8661 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8662 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008663#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008664
Hoonki Leea34dd892013-02-05 22:56:02 -08008665 /*Except teardown responder will not be used so just make 0*/
8666 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008667 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008668 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008669
8670 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308671 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008672
8673 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8674 responder = pTdlsPeer->is_responder;
8675 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008676 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8678 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
8679 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8680 dialog_token, status_code, len);
8681 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008682 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008683 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008684
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308685 /* For explicit trigger of DIS_REQ come out of BMPS for
8686 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008687 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308688 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8689 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008690 {
8691 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8692 {
8693 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308694 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008695 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8696 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308697 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8698 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008699 }
8700
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008701 /* make sure doesn't call send_mgmt() while it is pending */
8702 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8703 {
8704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008705 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008706 __func__, MAC_ADDR_ARRAY(peer), action_code);
8707 return -EBUSY;
8708 }
8709
8710 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008711 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8712
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008713 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08008714 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008715
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008716 if (VOS_STATUS_SUCCESS != status)
8717 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8719 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008720 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008721 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308722 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008723 }
8724
Hoonki Leed37cbb32013-04-20 00:31:14 -07008725 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8726 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8727
8728 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008729 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008731 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008732 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008733 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008734
8735 if (pHddCtx->isLogpInProgress)
8736 {
8737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8738 "%s: LOGP in Progress. Ignore!!!", __func__);
8739 return -EAGAIN;
8740 }
8741
Hoonki Leed37cbb32013-04-20 00:31:14 -07008742 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308743 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008744 }
8745
Gopichand Nakkala05922802013-03-14 12:23:19 -07008746 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008747 {
8748 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008749 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008750 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008751
Hoonki Leea34dd892013-02-05 22:56:02 -08008752 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8753 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008754 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008755 }
8756 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8757 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008758 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008759 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008760
8761 return 0;
8762}
8763
8764static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8765 u8 *peer, enum nl80211_tdls_operation oper)
8766{
8767 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8768 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308769 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008770 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008771
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308772 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008773 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008775 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008776 return -EINVAL;
8777 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008778
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308779 status = wlan_hdd_validate_context(pHddCtx);
8780
8781 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008782 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8784 "%s: HDD context is not valid", __func__);
8785 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008786 }
8787
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008788
8789 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008790 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008791 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008793 "TDLS Disabled in INI OR not enabled in FW. "
8794 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008795 return -ENOTSUPP;
8796 }
8797
8798 switch (oper) {
8799 case NL80211_TDLS_ENABLE_LINK:
8800 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008801 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308802 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308803 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008804
Sunil Dutt41de4e22013-11-14 18:09:02 +05308805 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8806
8807 if ( NULL == pTdlsPeer ) {
8808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8809 " (oper %d) not exsting. ignored",
8810 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8811 return -EINVAL;
8812 }
8813
8814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8815 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8816 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8817 "NL80211_TDLS_ENABLE_LINK");
8818
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07008819 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
8820 {
8821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
8822 MAC_ADDRESS_STR " failed",
8823 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
8824 return -EINVAL;
8825 }
8826
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008827 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008828 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308829 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05308830
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308831 if (0 != wlan_hdd_tdls_get_link_establish_params(
8832 pAdapter, peer,&tdlsLinkEstablishParams)) {
8833 return -EINVAL;
8834 }
8835 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308836
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308837 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
8838 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
8839 /* Send TDLS peer UAPSD capabilities to the firmware and
8840 * register with the TL on after the response for this operation
8841 * is received .
8842 */
8843 ret = wait_for_completion_interruptible_timeout(
8844 &pAdapter->tdls_link_establish_req_comp,
8845 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
8846 if (ret <= 0)
8847 {
8848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8849 "%s: Link Establish Request Faled Status %ld",
8850 __func__, ret);
8851 return -EINVAL;
8852 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308853 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008854 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05308855 /* Mark TDLS client Authenticated .*/
8856 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
8857 pTdlsPeer->staId,
8858 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008859 if (VOS_STATUS_SUCCESS == status)
8860 {
Hoonki Lee14621352013-04-16 17:51:19 -07008861 if (pTdlsPeer->is_responder == 0)
8862 {
8863 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
8864
8865 wlan_hdd_tdls_timer_restart(pAdapter,
8866 &pTdlsPeer->initiatorWaitTimeoutTimer,
8867 WAIT_TIME_TDLS_INITIATOR);
8868 /* suspend initiator TX until it receives direct packet from the
8869 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
8870 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8871 &staId, NULL);
8872 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008873 wlan_hdd_tdls_increment_peer_count(pAdapter);
8874 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008875 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308876
8877 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308878 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
8879 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308880 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308881 int ac;
8882 uint8 ucAc[4] = { WLANTL_AC_VO,
8883 WLANTL_AC_VI,
8884 WLANTL_AC_BK,
8885 WLANTL_AC_BE };
8886 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
8887 for(ac=0; ac < 4; ac++)
8888 {
8889 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8890 pTdlsPeer->staId, ucAc[ac],
8891 tlTid[ac], tlTid[ac], 0, 0,
8892 WLANTL_BI_DIR );
8893 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308894 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008895 }
8896
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008897 }
8898 break;
8899 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08008900 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05308901 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8902
8903 if ( NULL == pTdlsPeer ) {
8904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8905 " (oper %d) not exsting. ignored",
8906 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8907 return -EINVAL;
8908 }
8909
8910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8911 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8912 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8913 "NL80211_TDLS_DISABLE_LINK");
8914
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008915 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008916 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008917 long status;
8918
8919 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
8920
Lee Hoonkic1262f22013-01-24 21:59:00 -08008921 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
8922 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008923
8924 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
8925 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
8926 if (status <= 0)
8927 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008928 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8930 "%s: Del station failed status %ld",
8931 __func__, status);
8932 return -EPERM;
8933 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008934 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008935 }
8936 else
8937 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8939 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008940 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008941 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008942 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008943 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308944 {
8945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8946 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
8947 __func__, MAC_ADDR_ARRAY(peer));
8948
8949 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8950 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8951
8952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8953 " %s TDLS External control and Implicit Trigger not enabled ",
8954 __func__);
8955 return -ENOTSUPP;
8956 }
8957
Sunil Dutt41de4e22013-11-14 18:09:02 +05308958
8959 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8960
8961 if ( NULL == pTdlsPeer ) {
8962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
8963 " peer not exsting",
8964 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308965 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308966 }
8967 else {
8968 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
8969 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
8970 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308971
8972 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
8973 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308974 break;
8975 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008976 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308977 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308978 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8980 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
8981 __func__, MAC_ADDR_ARRAY(peer));
8982
8983 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8984 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8985
8986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8987 " %s TDLS External control and Implicit Trigger not enabled ",
8988 __func__);
8989 return -ENOTSUPP;
8990 }
8991
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308992 /* To cater the requirement of establishing the TDLS link
8993 * irrespective of the data traffic , get an entry of TDLS peer.
8994 */
8995 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
8996 if (pTdlsPeer == NULL) {
8997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8998 "%s: peer " MAC_ADDRESS_STR " not existing",
8999 __func__, MAC_ADDR_ARRAY(peer));
9000 return -EINVAL;
9001 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309002
9003 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9004
9005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9006 " %s TDLS Add Force Peer Failed",
9007 __func__);
9008 return -EINVAL;
9009 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309010 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309011 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009012 case NL80211_TDLS_DISCOVERY_REQ:
9013 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9015 "%s: We don't support in-driver setup/teardown/discovery "
9016 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009017 return -ENOTSUPP;
9018 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9020 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009021 return -ENOTSUPP;
9022 }
9023 return 0;
9024}
Chilam NG571c65a2013-01-19 12:27:36 +05309025
9026int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9027 struct net_device *dev, u8 *peer)
9028{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009029 hddLog(VOS_TRACE_LEVEL_INFO,
9030 "tdls send discover req: "MAC_ADDRESS_STR,
9031 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309032
9033 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9034 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
9035}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009036#endif
9037
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309038#ifdef WLAN_FEATURE_GTK_OFFLOAD
9039/*
9040 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9041 * Callback rountine called upon receiving response for
9042 * get offload info
9043 */
9044void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9045 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9046{
9047
9048 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309049 tANI_U8 tempReplayCounter[8];
9050 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309051
9052 ENTER();
9053
9054 if (NULL == pAdapter)
9055 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309057 "%s: HDD adapter is Null", __func__);
9058 return ;
9059 }
9060
9061 if (NULL == pGtkOffloadGetInfoRsp)
9062 {
9063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9064 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9065 return ;
9066 }
9067
9068 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9069 {
9070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9071 "%s: wlan Failed to get replay counter value",
9072 __func__);
9073 return ;
9074 }
9075
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309076 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9077 /* Update replay counter */
9078 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9079 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9080
9081 {
9082 /* changing from little to big endian since supplicant
9083 * works on big endian format
9084 */
9085 int i;
9086 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9087
9088 for (i = 0; i < 8; i++)
9089 {
9090 tempReplayCounter[7-i] = (tANI_U8)p[i];
9091 }
9092 }
9093
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309094 /* Update replay counter to NL */
9095 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309096 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309097}
9098
9099/*
9100 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9101 * This function is used to offload GTK rekeying job to the firmware.
9102 */
9103int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9104 struct cfg80211_gtk_rekey_data *data)
9105{
9106 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9107 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9108 hdd_station_ctx_t *pHddStaCtx;
9109 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309110 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309111 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309112 eHalStatus status = eHAL_STATUS_FAILURE;
9113
9114 ENTER();
9115
9116 if (NULL == pAdapter)
9117 {
9118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9119 "%s: HDD adapter is Null", __func__);
9120 return -ENODEV;
9121 }
9122
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309123 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309124
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309125 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309126 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9128 "%s: HDD context is not valid", __func__);
9129 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309130 }
9131
9132 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9133 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9134 if (NULL == hHal)
9135 {
9136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9137 "%s: HAL context is Null!!!", __func__);
9138 return -EAGAIN;
9139 }
9140
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309141 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9142 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9143 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9144 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309145 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309146 {
9147 /* changing from big to little endian since driver
9148 * works on little endian format
9149 */
9150 tANI_U8 *p =
9151 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9152 int i;
9153
9154 for (i = 0; i < 8; i++)
9155 {
9156 p[7-i] = data->replay_ctr[i];
9157 }
9158 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309159
9160 if (TRUE == pHddCtx->hdd_wlan_suspended)
9161 {
9162 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309163 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9164 sizeof (tSirGtkOffloadParams));
9165 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309166 pAdapter->sessionId);
9167
9168 if (eHAL_STATUS_SUCCESS != status)
9169 {
9170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9171 "%s: sme_SetGTKOffload failed, returned %d",
9172 __func__, status);
9173 return status;
9174 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9176 "%s: sme_SetGTKOffload successfull", __func__);
9177 }
9178 else
9179 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9181 "%s: wlan not suspended GTKOffload request is stored",
9182 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309183 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309184
9185 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309186}
9187#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9188
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309189/*
9190 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9191 * This function is used to set access control policy
9192 */
9193static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9194 struct net_device *dev, const struct cfg80211_acl_data *params)
9195{
9196 int i;
9197 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9198 hdd_hostapd_state_t *pHostapdState;
9199 tsap_Config_t *pConfig;
9200 v_CONTEXT_t pVosContext = NULL;
9201 hdd_context_t *pHddCtx;
9202 int status;
9203
9204 ENTER();
9205
9206 if (NULL == pAdapter)
9207 {
9208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9209 "%s: HDD adapter is Null", __func__);
9210 return -ENODEV;
9211 }
9212
9213 if (NULL == params)
9214 {
9215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9216 "%s: params is Null", __func__);
9217 return -EINVAL;
9218 }
9219
9220 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9221 status = wlan_hdd_validate_context(pHddCtx);
9222
9223 if (0 != status)
9224 {
9225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9226 "%s: HDD context is not valid", __func__);
9227 return status;
9228 }
9229
9230 pVosContext = pHddCtx->pvosContext;
9231 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9232
9233 if (NULL == pHostapdState)
9234 {
9235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9236 "%s: pHostapdState is Null", __func__);
9237 return -EINVAL;
9238 }
9239
9240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9241 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9242
9243 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9244 {
9245 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9246
9247 /* default value */
9248 pConfig->num_accept_mac = 0;
9249 pConfig->num_deny_mac = 0;
9250
9251 /**
9252 * access control policy
9253 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9254 * listed in hostapd.deny file.
9255 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9256 * listed in hostapd.accept file.
9257 */
9258 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9259 {
9260 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9261 }
9262 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9263 {
9264 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9265 }
9266 else
9267 {
9268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9269 "%s:Acl Policy : %d is not supported",
9270 __func__, params->acl_policy);
9271 return -ENOTSUPP;
9272 }
9273
9274 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9275 {
9276 pConfig->num_accept_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 WhiletList :"
9281 MAC_ADDRESS_STR, i,
9282 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9283
9284 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9285 sizeof(qcmacaddr));
9286 }
9287 }
9288 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9289 {
9290 pConfig->num_deny_mac = params->n_acl_entries;
9291 for (i = 0; i < params->n_acl_entries; i++)
9292 {
9293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9294 "** Add ACL MAC entry %i in BlackList :"
9295 MAC_ADDRESS_STR, i,
9296 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9297
9298 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9299 sizeof(qcmacaddr));
9300 }
9301 }
9302
9303 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9304 {
9305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9306 "%s: SAP Set Mac Acl fail", __func__);
9307 return -EINVAL;
9308 }
9309 }
9310 else
9311 {
9312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9313 "%s: Invalid device_mode = %d",
9314 __func__, pAdapter->device_mode);
9315 return -EINVAL;
9316 }
9317
9318 return 0;
9319}
9320
Leo Chang9056f462013-08-01 19:21:11 -07009321#ifdef WLAN_NL80211_TESTMODE
9322#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009323void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009324(
9325 void *pAdapter,
9326 void *indCont
9327)
9328{
Leo Changd9df8aa2013-09-26 13:32:26 -07009329 tSirLPHBInd *lphbInd;
9330 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009331
9332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009333 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009334
9335 if (NULL == indCont)
9336 {
9337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009338 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009339 return;
9340 }
9341
Leo Changd9df8aa2013-09-26 13:32:26 -07009342 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009343 skb = cfg80211_testmode_alloc_event_skb(
9344 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009345 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009346 GFP_ATOMIC);
9347 if (!skb)
9348 {
9349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9350 "LPHB timeout, NL buffer alloc fail");
9351 return;
9352 }
9353
Leo Changac3ba772013-10-07 09:47:04 -07009354 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009355 {
9356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9357 "WLAN_HDD_TM_ATTR_CMD put fail");
9358 goto nla_put_failure;
9359 }
Leo Changac3ba772013-10-07 09:47:04 -07009360 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009361 {
9362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9363 "WLAN_HDD_TM_ATTR_TYPE put fail");
9364 goto nla_put_failure;
9365 }
Leo Changac3ba772013-10-07 09:47:04 -07009366 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009367 sizeof(tSirLPHBInd), lphbInd))
9368 {
9369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9370 "WLAN_HDD_TM_ATTR_DATA put fail");
9371 goto nla_put_failure;
9372 }
Leo Chang9056f462013-08-01 19:21:11 -07009373 cfg80211_testmode_event(skb, GFP_ATOMIC);
9374 return;
9375
9376nla_put_failure:
9377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9378 "NLA Put fail");
9379 kfree_skb(skb);
9380
9381 return;
9382}
9383#endif /* FEATURE_WLAN_LPHB */
9384
9385static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9386{
9387 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9388 int err = 0;
9389#ifdef FEATURE_WLAN_LPHB
9390 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009391 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009392#endif /* FEATURE_WLAN_LPHB */
9393
9394 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9395 if (err)
9396 {
9397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9398 "%s Testmode INV ATTR", __func__);
9399 return err;
9400 }
9401
9402 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9403 {
9404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9405 "%s Testmode INV CMD", __func__);
9406 return -EINVAL;
9407 }
9408
9409 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9410 {
9411#ifdef FEATURE_WLAN_LPHB
9412 /* Low Power Heartbeat configuration request */
9413 case WLAN_HDD_TM_CMD_WLAN_HB:
9414 {
9415 int buf_len;
9416 void *buf;
9417 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009418 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009419
9420 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9421 {
9422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9423 "%s Testmode INV DATA", __func__);
9424 return -EINVAL;
9425 }
9426
9427 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9428 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009429
9430 hb_params_temp =(tSirLPHBReq *)buf;
9431 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9432 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9433 return -EINVAL;
9434
Leo Chang9056f462013-08-01 19:21:11 -07009435 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9436 if (NULL == hb_params)
9437 {
9438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 "%s Request Buffer Alloc Fail", __func__);
9440 return -EINVAL;
9441 }
9442
9443 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009444 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9445 hb_params,
9446 wlan_hdd_cfg80211_lphb_ind_handler);
9447 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009448 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9450 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009451 vos_mem_free(hb_params);
9452 }
Leo Chang9056f462013-08-01 19:21:11 -07009453 return 0;
9454 }
9455#endif /* FEATURE_WLAN_LPHB */
9456 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9458 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009459 return -EOPNOTSUPP;
9460 }
9461
9462 return err;
9463}
9464#endif /* CONFIG_NL80211_TESTMODE */
9465
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309466static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9467 struct net_device *dev,
9468 int idx, struct survey_info *survey)
9469{
9470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9471 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309472 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309473 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309474 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309475 v_S7_t snr,rssi;
9476 int status, i, j, filled = 0;
9477
9478 ENTER();
9479
9480
9481 if (NULL == pAdapter)
9482 {
9483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9484 "%s: HDD adapter is Null", __func__);
9485 return -ENODEV;
9486 }
9487
9488 if (NULL == wiphy)
9489 {
9490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9491 "%s: wiphy is Null", __func__);
9492 return -ENODEV;
9493 }
9494
9495 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9496 status = wlan_hdd_validate_context(pHddCtx);
9497
9498 if (0 != status)
9499 {
9500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9501 "%s: HDD context is not valid", __func__);
9502 return status;
9503 }
9504
Mihir Sheted9072e02013-08-21 17:02:29 +05309505 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9506
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309507 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309508 0 != pAdapter->survey_idx ||
9509 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309510 {
9511 /* The survey dump ops when implemented completely is expected to
9512 * return a survey of all channels and the ops is called by the
9513 * kernel with incremental values of the argument 'idx' till it
9514 * returns -ENONET. But we can only support the survey for the
9515 * operating channel for now. survey_idx is used to track
9516 * that the ops is called only once and then return -ENONET for
9517 * the next iteration
9518 */
9519 pAdapter->survey_idx = 0;
9520 return -ENONET;
9521 }
9522
9523 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9524
9525 wlan_hdd_get_snr(pAdapter, &snr);
9526 wlan_hdd_get_rssi(pAdapter, &rssi);
9527
9528 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9529 hdd_wlan_get_freq(channel, &freq);
9530
9531
9532 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9533 {
9534 if (NULL == wiphy->bands[i])
9535 {
9536 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9537 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9538 continue;
9539 }
9540
9541 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9542 {
9543 struct ieee80211_supported_band *band = wiphy->bands[i];
9544
9545 if (band->channels[j].center_freq == (v_U16_t)freq)
9546 {
9547 survey->channel = &band->channels[j];
9548 /* The Rx BDs contain SNR values in dB for the received frames
9549 * while the supplicant expects noise. So we calculate and
9550 * return the value of noise (dBm)
9551 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9552 */
9553 survey->noise = rssi - snr;
9554 survey->filled = SURVEY_INFO_NOISE_DBM;
9555 filled = 1;
9556 }
9557 }
9558 }
9559
9560 if (filled)
9561 pAdapter->survey_idx = 1;
9562 else
9563 {
9564 pAdapter->survey_idx = 0;
9565 return -ENONET;
9566 }
9567
9568 return 0;
9569}
9570
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309571/*
9572 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9573 * this is called when cfg80211 driver resume
9574 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9575 */
9576int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9577{
9578 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9579 hdd_adapter_t *pAdapter;
9580 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9581 VOS_STATUS status = VOS_STATUS_SUCCESS;
9582
9583 ENTER();
9584
9585 if ( NULL == pHddCtx )
9586 {
9587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9588 "%s: HddCtx validation failed", __func__);
9589 return 0;
9590 }
9591
9592 if (pHddCtx->isLogpInProgress)
9593 {
9594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9595 "%s: LOGP in Progress. Ignore!!!", __func__);
9596 return 0;
9597 }
9598
9599 if (pHddCtx->isLoadUnloadInProgress)
9600 {
9601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9602 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9603 return 0;
9604 }
9605
9606 spin_lock(&pHddCtx->schedScan_lock);
9607 pHddCtx->isWiphySuspended = FALSE;
9608 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9609 {
9610 spin_unlock(&pHddCtx->schedScan_lock);
9611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9612 "%s: Return resume is not due to PNO indication", __func__);
9613 return 0;
9614 }
9615 // Reset flag to avoid updatating cfg80211 data old results again
9616 pHddCtx->isSchedScanUpdatePending = FALSE;
9617 spin_unlock(&pHddCtx->schedScan_lock);
9618
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309619
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309620 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9621
9622 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9623 {
9624 pAdapter = pAdapterNode->pAdapter;
9625 if ( (NULL != pAdapter) &&
9626 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9627 {
9628 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309629 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9631 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309632 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309633 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309634 {
9635 /* Acquire wakelock to handle the case where APP's tries to
9636 * suspend immediately after updating the scan results. Whis
9637 * results in app's is in suspended state and not able to
9638 * process the connect request to AP
9639 */
9640 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309641 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309642 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309643
9644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9645 "%s : cfg80211 scan result database updated", __func__);
9646
9647 return 0;
9648
9649 }
9650 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9651 pAdapterNode = pNext;
9652 }
9653
9654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9655 "%s: Failed to find Adapter", __func__);
9656 return 0;
9657}
9658
9659/*
9660 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9661 * this is called when cfg80211 driver suspends
9662 */
9663int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9664 struct cfg80211_wowlan *wow)
9665{
9666 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9667
9668 ENTER();
9669 if (NULL == pHddCtx)
9670 {
9671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9672 "%s: HddCtx validation failed", __func__);
9673 return 0;
9674 }
9675
9676 pHddCtx->isWiphySuspended = TRUE;
9677
9678 EXIT();
9679
9680 return 0;
9681}
9682
Jeff Johnson295189b2012-06-20 16:38:30 -07009683/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009685{
9686 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9687 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9688 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9689 .change_station = wlan_hdd_change_station,
9690#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9691 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9692 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9693 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009694#else
9695 .start_ap = wlan_hdd_cfg80211_start_ap,
9696 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9697 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009698#endif
9699 .change_bss = wlan_hdd_cfg80211_change_bss,
9700 .add_key = wlan_hdd_cfg80211_add_key,
9701 .get_key = wlan_hdd_cfg80211_get_key,
9702 .del_key = wlan_hdd_cfg80211_del_key,
9703 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009704#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 .scan = wlan_hdd_cfg80211_scan,
9708 .connect = wlan_hdd_cfg80211_connect,
9709 .disconnect = wlan_hdd_cfg80211_disconnect,
9710 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9711 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9712 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9713 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9714 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9716 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
9717 .mgmt_tx = wlan_hdd_action,
9718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9719 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9720 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9721 .set_txq_params = wlan_hdd_set_txq_params,
9722#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 .get_station = wlan_hdd_cfg80211_get_station,
9724 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9725 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009726 .add_station = wlan_hdd_cfg80211_add_station,
9727#ifdef FEATURE_WLAN_LFR
9728 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9729 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9730 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9731#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009732#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9733 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9734#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009735#ifdef FEATURE_WLAN_TDLS
9736 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9737 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9738#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309739#ifdef WLAN_FEATURE_GTK_OFFLOAD
9740 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9741#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309742#ifdef FEATURE_WLAN_SCAN_PNO
9743 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9744 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9745#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309746 .resume = wlan_hdd_cfg80211_resume_wlan,
9747 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309748 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009749#ifdef WLAN_NL80211_TESTMODE
9750 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9751#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309752 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009753};
9754