blob: 85739de6c9567a58f633b1d9030ee2333e1eb065 [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"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530146static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700147{
148 WLAN_CIPHER_SUITE_WEP40,
149 WLAN_CIPHER_SUITE_WEP104,
150 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700152#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
153 WLAN_CIPHER_SUITE_KRK,
154 WLAN_CIPHER_SUITE_CCMP,
155#else
156 WLAN_CIPHER_SUITE_CCMP,
157#endif
158#ifdef FEATURE_WLAN_WAPI
159 WLAN_CIPHER_SUITE_SMS4,
160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700161#ifdef WLAN_FEATURE_11W
162 WLAN_CIPHER_SUITE_AES_CMAC,
163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700164};
165
166static inline int is_broadcast_ether_addr(const u8 *addr)
167{
168 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
169 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
170}
171
172static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173{
Jeff Johnson295189b2012-06-20 16:38:30 -0700174 HDD2GHZCHAN(2412, 1, 0) ,
175 HDD2GHZCHAN(2417, 2, 0) ,
176 HDD2GHZCHAN(2422, 3, 0) ,
177 HDD2GHZCHAN(2427, 4, 0) ,
178 HDD2GHZCHAN(2432, 5, 0) ,
179 HDD2GHZCHAN(2437, 6, 0) ,
180 HDD2GHZCHAN(2442, 7, 0) ,
181 HDD2GHZCHAN(2447, 8, 0) ,
182 HDD2GHZCHAN(2452, 9, 0) ,
183 HDD2GHZCHAN(2457, 10, 0) ,
184 HDD2GHZCHAN(2462, 11, 0) ,
185 HDD2GHZCHAN(2467, 12, 0) ,
186 HDD2GHZCHAN(2472, 13, 0) ,
187 HDD2GHZCHAN(2484, 14, 0) ,
188};
189
Jeff Johnson295189b2012-06-20 16:38:30 -0700190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
197static struct ieee80211_channel hdd_channels_5_GHZ[] =
198{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700199 HDD5GHZCHAN(4920, 240, 0) ,
200 HDD5GHZCHAN(4940, 244, 0) ,
201 HDD5GHZCHAN(4960, 248, 0) ,
202 HDD5GHZCHAN(4980, 252, 0) ,
203 HDD5GHZCHAN(5040, 208, 0) ,
204 HDD5GHZCHAN(5060, 212, 0) ,
205 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 HDD5GHZCHAN(5180, 36, 0) ,
207 HDD5GHZCHAN(5200, 40, 0) ,
208 HDD5GHZCHAN(5220, 44, 0) ,
209 HDD5GHZCHAN(5240, 48, 0) ,
210 HDD5GHZCHAN(5260, 52, 0) ,
211 HDD5GHZCHAN(5280, 56, 0) ,
212 HDD5GHZCHAN(5300, 60, 0) ,
213 HDD5GHZCHAN(5320, 64, 0) ,
214 HDD5GHZCHAN(5500,100, 0) ,
215 HDD5GHZCHAN(5520,104, 0) ,
216 HDD5GHZCHAN(5540,108, 0) ,
217 HDD5GHZCHAN(5560,112, 0) ,
218 HDD5GHZCHAN(5580,116, 0) ,
219 HDD5GHZCHAN(5600,120, 0) ,
220 HDD5GHZCHAN(5620,124, 0) ,
221 HDD5GHZCHAN(5640,128, 0) ,
222 HDD5GHZCHAN(5660,132, 0) ,
223 HDD5GHZCHAN(5680,136, 0) ,
224 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800225#ifdef FEATURE_WLAN_CH144
226 HDD5GHZCHAN(5720,144, 0) ,
227#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5745,149, 0) ,
229 HDD5GHZCHAN(5765,153, 0) ,
230 HDD5GHZCHAN(5785,157, 0) ,
231 HDD5GHZCHAN(5805,161, 0) ,
232 HDD5GHZCHAN(5825,165, 0) ,
233};
234
235static struct ieee80211_rate g_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(10, 0x1, 0),
238 HDD_G_MODE_RATETAB(20, 0x2, 0),
239 HDD_G_MODE_RATETAB(55, 0x4, 0),
240 HDD_G_MODE_RATETAB(110, 0x8, 0),
241 HDD_G_MODE_RATETAB(60, 0x10, 0),
242 HDD_G_MODE_RATETAB(90, 0x20, 0),
243 HDD_G_MODE_RATETAB(120, 0x40, 0),
244 HDD_G_MODE_RATETAB(180, 0x80, 0),
245 HDD_G_MODE_RATETAB(240, 0x100, 0),
246 HDD_G_MODE_RATETAB(360, 0x200, 0),
247 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700248 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530249};
Jeff Johnson295189b2012-06-20 16:38:30 -0700250
251static struct ieee80211_rate a_mode_rates[] =
252{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530253 HDD_G_MODE_RATETAB(60, 0x10, 0),
254 HDD_G_MODE_RATETAB(90, 0x20, 0),
255 HDD_G_MODE_RATETAB(120, 0x40, 0),
256 HDD_G_MODE_RATETAB(180, 0x80, 0),
257 HDD_G_MODE_RATETAB(240, 0x100, 0),
258 HDD_G_MODE_RATETAB(360, 0x200, 0),
259 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 HDD_G_MODE_RATETAB(540, 0x800, 0),
261};
262
263static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
264{
265 .channels = hdd_channels_2_4_GHZ,
266 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
267 .band = IEEE80211_BAND_2GHZ,
268 .bitrates = g_mode_rates,
269 .n_bitrates = g_mode_rates_size,
270 .ht_cap.ht_supported = 1,
271 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
272 | IEEE80211_HT_CAP_GRN_FLD
273 | IEEE80211_HT_CAP_DSSSCCK40
274 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
275 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
276 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
277 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
278 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
279 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
280};
281
Jeff Johnson295189b2012-06-20 16:38:30 -0700282static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
283{
284 .channels = hdd_social_channels_2_4_GHZ,
285 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
286 .band = IEEE80211_BAND_2GHZ,
287 .bitrates = g_mode_rates,
288 .n_bitrates = g_mode_rates_size,
289 .ht_cap.ht_supported = 1,
290 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
291 | IEEE80211_HT_CAP_GRN_FLD
292 | IEEE80211_HT_CAP_DSSSCCK40
293 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
294 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
295 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
296 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
297 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
298 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
299};
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530322/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700341 [NL80211_IFTYPE_ADHOC] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 [NL80211_IFTYPE_P2P_CLIENT] = {
352 .tx = 0xffff,
353 .rx = BIT(SIR_MAC_MGMT_ACTION) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ),
355 },
356 [NL80211_IFTYPE_P2P_GO] = {
357 /* This is also same as for SoftAP */
358 .tx = 0xffff,
359 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_PROBE_REQ) |
362 BIT(SIR_MAC_MGMT_DISASSOC) |
363 BIT(SIR_MAC_MGMT_AUTH) |
364 BIT(SIR_MAC_MGMT_DEAUTH) |
365 BIT(SIR_MAC_MGMT_ACTION),
366 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700367};
368
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800370static const struct ieee80211_iface_limit
371wlan_hdd_iface_limit[] = {
372 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800373 /* max = 3 ; Our driver create two interfaces during driver init
374 * wlan0 and p2p0 interfaces. p2p0 is considered as station
375 * interface until a group is formed. In JB architecture, once the
376 * group is formed, interface type of p2p0 is changed to P2P GO or
377 * Client.
378 * When supplicant remove the group, it first issue a set interface
379 * cmd to change the mode back to Station. In JB this works fine as
380 * we advertize two station type interface during driver init.
381 * Some vendors create separate interface for P2P GO/Client,
382 * after group formation(Third one). But while group remove
383 * supplicant first tries to change the mode(3rd interface) to STATION
384 * But as we advertized only two sta type interfaces nl80211 was
385 * returning error for the third one which was leading to failure in
386 * delete interface. Ideally while removing the group, supplicant
387 * should not try to change the 3rd interface mode to Station type.
388 * Till we get a fix in wpa_supplicant, we advertize max STA
389 * interface type to 3
390 */
391 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392 .types = BIT(NL80211_IFTYPE_STATION),
393 },
394 {
395 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700396 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397 },
398 {
399 .max = 1,
400 .types = BIT(NL80211_IFTYPE_P2P_GO) |
401 BIT(NL80211_IFTYPE_P2P_CLIENT),
402 },
403};
404
405/* By default, only single channel concurrency is allowed */
406static struct ieee80211_iface_combination
407wlan_hdd_iface_combination = {
408 .limits = wlan_hdd_iface_limit,
409 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800410 /*
411 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
412 * and p2p0 interfaces during driver init
413 * Some vendors create separate interface for P2P operations.
414 * wlan0: STA interface
415 * p2p0: P2P Device interface, action frames goes
416 * through this interface.
417 * p2p-xx: P2P interface, After GO negotiation this interface is
418 * created for p2p operations(GO/CLIENT interface).
419 */
420 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
422 .beacon_int_infra_match = false,
423};
424#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426static struct cfg80211_ops wlan_hdd_cfg80211_ops;
427
428/* Data rate 100KBPS based on IE Index */
429struct index_data_rate_type
430{
431 v_U8_t beacon_rate_index;
432 v_U16_t supported_rate[4];
433};
434
435/* 11B, 11G Rate table include Basic rate and Extended rate
436 The IDX field is the rate index
437 The HI field is the rate when RSSI is strong or being ignored
438 (in this case we report actual rate)
439 The MID field is the rate when RSSI is moderate
440 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
441 The LO field is the rate when RSSI is low
442 (in this case we don't report rates, actual current rate used)
443 */
444static const struct
445{
446 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700448} supported_data_rate[] =
449{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700450/* IDX HI HM LM LO (RSSI-based index */
451 {2, { 10, 10, 10, 0}},
452 {4, { 20, 20, 10, 0}},
453 {11, { 55, 20, 10, 0}},
454 {12, { 60, 55, 20, 0}},
455 {18, { 90, 55, 20, 0}},
456 {22, {110, 55, 20, 0}},
457 {24, {120, 90, 60, 0}},
458 {36, {180, 120, 60, 0}},
459 {44, {220, 180, 60, 0}},
460 {48, {240, 180, 90, 0}},
461 {66, {330, 180, 90, 0}},
462 {72, {360, 240, 90, 0}},
463 {96, {480, 240, 120, 0}},
464 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465};
466
467/* MCS Based rate table */
468static struct index_data_rate_type supported_mcs_rate[] =
469{
470/* MCS L20 L40 S20 S40 */
471 {0, {65, 135, 72, 150}},
472 {1, {130, 270, 144, 300}},
473 {2, {195, 405, 217, 450}},
474 {3, {260, 540, 289, 600}},
475 {4, {390, 810, 433, 900}},
476 {5, {520, 1080, 578, 1200}},
477 {6, {585, 1215, 650, 1350}},
478 {7, {650, 1350, 722, 1500}}
479};
480
Leo Chang6f8870f2013-03-26 18:11:36 -0700481#ifdef WLAN_FEATURE_11AC
482
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530483#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700484
485struct index_vht_data_rate_type
486{
487 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488 v_U16_t supported_VHT80_rate[2];
489 v_U16_t supported_VHT40_rate[2];
490 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700491};
492
493typedef enum
494{
495 DATA_RATE_11AC_MAX_MCS_7,
496 DATA_RATE_11AC_MAX_MCS_8,
497 DATA_RATE_11AC_MAX_MCS_9,
498 DATA_RATE_11AC_MAX_MCS_NA
499} eDataRate11ACMaxMcs;
500
501/* MCS Based VHT rate table */
502static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
503{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530504/* MCS L80 S80 L40 S40 L20 S40*/
505 {0, {293, 325}, {135, 150}, {65, 72}},
506 {1, {585, 650}, {270, 300}, {130, 144}},
507 {2, {878, 975}, {405, 450}, {195, 217}},
508 {3, {1170, 1300}, {540, 600}, {260, 289}},
509 {4, {1755, 1950}, {810, 900}, {390, 433}},
510 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
511 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
512 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
513 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
514 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700515};
516#endif /* WLAN_FEATURE_11AC */
517
Jeff Johnson295189b2012-06-20 16:38:30 -0700518extern struct net_device_ops net_ops_struct;
519
Leo Chang9056f462013-08-01 19:21:11 -0700520#ifdef WLAN_NL80211_TESTMODE
521enum wlan_hdd_tm_attr
522{
523 WLAN_HDD_TM_ATTR_INVALID = 0,
524 WLAN_HDD_TM_ATTR_CMD = 1,
525 WLAN_HDD_TM_ATTR_DATA = 2,
526 WLAN_HDD_TM_ATTR_TYPE = 3,
527 /* keep last */
528 WLAN_HDD_TM_ATTR_AFTER_LAST,
529 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
530};
531
532enum wlan_hdd_tm_cmd
533{
534 WLAN_HDD_TM_CMD_WLAN_HB = 1,
535};
536
537#define WLAN_HDD_TM_DATA_MAX_LEN 5000
538
539static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
540{
541 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
542 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
543 .len = WLAN_HDD_TM_DATA_MAX_LEN },
544};
545#endif /* WLAN_NL80211_TESTMODE */
546
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800547#ifdef FEATURE_WLAN_CH_AVOID
548/*
549 * FUNCTION: wlan_hdd_send_avoid_freq_event
550 * This is called when wlan driver needs to send vendor specific
551 * avoid frequency range event to userspace
552 */
553int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
554 tHddAvoidFreqList *pAvoidFreqList)
555{
556 struct sk_buff *vendor_event;
557
558 ENTER();
559
560 if (!pHddCtx)
561 {
562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
563 "%s: HDD context is null", __func__);
564 return -1;
565 }
566
567 if (!pAvoidFreqList)
568 {
569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
570 "%s: pAvoidFreqList is null", __func__);
571 return -1;
572 }
573
574 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
575 sizeof(tHddAvoidFreqList),
576 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
577 GFP_KERNEL);
578 if (!vendor_event)
579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
581 "%s: cfg80211_vendor_event_alloc failed", __func__);
582 return -1;
583 }
584
585 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
586 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
587
588 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
589
590 EXIT();
591 return 0;
592}
593#endif /* FEATURE_WLAN_CH_AVOID */
594
595/* vendor specific events */
596static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
597{
598#ifdef FEATURE_WLAN_CH_AVOID
599 {
600 .vendor_id = QCOM_NL80211_VENDOR_ID,
601 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
602 },
603#endif /* FEATURE_WLAN_CH_AVOID */
604};
605
Jeff Johnson295189b2012-06-20 16:38:30 -0700606/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530608 * This function is called by hdd_wlan_startup()
609 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530610 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530612struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700613{
614 struct wiphy *wiphy;
615 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530616 /*
617 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 */
619 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
620
621 if (!wiphy)
622 {
623 /* Print error and jump into err label and free the memory */
624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
625 return NULL;
626 }
627
628 return wiphy;
629}
630
631/*
632 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530633 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 * private ioctl to change the band value
635 */
636int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530638 int i, j;
639 eNVChannelEnabledType channelEnabledState;
640
Jeff Johnsone7245742012-09-05 17:12:55 -0700641 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530642
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530643 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530645
646 if (NULL == wiphy->bands[i])
647 {
648 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
649 __func__, i);
650 continue;
651 }
652
653 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
654 {
655 struct ieee80211_supported_band *band = wiphy->bands[i];
656
657 channelEnabledState = vos_nv_getChannelEnabledState(
658 band->channels[j].hw_value);
659
660 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
661 {
662 // Enable Social channels for P2P
663 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
664 NV_CHANNEL_ENABLE == channelEnabledState)
665 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
666 else
667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
668 continue;
669 }
670 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
671 {
672 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
673 continue;
674 }
675
676 if (NV_CHANNEL_DISABLE == channelEnabledState ||
677 NV_CHANNEL_INVALID == channelEnabledState)
678 {
679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
680 }
681 else if (NV_CHANNEL_DFS == channelEnabledState)
682 {
683 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
684 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
685 }
686 else
687 {
688 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
689 |IEEE80211_CHAN_RADAR);
690 }
691 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 }
693 return 0;
694}
695/*
696 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530697 * This function is called by hdd_wlan_startup()
698 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 * This function is used to initialize and register wiphy structure.
700 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530701int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 struct wiphy *wiphy,
703 hdd_config_t *pCfg
704 )
705{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530706 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
708
Jeff Johnsone7245742012-09-05 17:12:55 -0700709 ENTER();
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Now bind the underlying wlan device with wiphy */
712 set_wiphy_dev(wiphy, dev);
713
714 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700715
Kiet Lam6c583332013-10-14 05:37:09 +0530716#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700717 /* the flag for the other case would be initialzed in
718 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700719 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530720#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700721
Amar Singhalfddc28c2013-09-05 13:03:40 -0700722 /* This will disable updating of NL channels from passive to
723 * active if a beacon is received on passive channel. */
724 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700725
Amar Singhalfddc28c2013-09-05 13:03:40 -0700726
Amar Singhala49cbc52013-10-08 18:37:44 -0700727
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700729 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
730 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
731 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700732 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530733 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700734#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700735
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800736#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700737 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800738#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700739 || pCfg->isFastRoamIniFeatureEnabled
740#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800741#ifdef FEATURE_WLAN_ESE
742 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700743#endif
744 )
745 {
746 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
747 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800748#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800749#ifdef FEATURE_WLAN_TDLS
750 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
751 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
752#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530753#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530754 if (pCfg->configPNOScanSupport)
755 {
756 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
757 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
758 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
759 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
760 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530761#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800762
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
765 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700767 driver need to determine what to do with both
768 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700769
770 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700771#else
772 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700773#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700774
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775 wiphy->max_scan_ssids = MAX_SCAN_SSID;
776
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530777 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700778
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530779 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
780
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530782 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 | BIT(NL80211_IFTYPE_P2P_CLIENT)
785 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 | BIT(NL80211_IFTYPE_AP);
787
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530788 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800789 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
791 if( pCfg->enableMCC )
792 {
793 /* Currently, supports up to two channels */
794 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 if( !pCfg->allowMCCGODiffBI )
797 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800798
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530799 }
800 wiphy->iface_combinations = &wlan_hdd_iface_combination;
801 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800802#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530803 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 /* Before registering we need to update the ht capabilitied based
806 * on ini values*/
807 if( !pCfg->ShortGI20MhzEnable )
808 {
809 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
810 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
811 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
812 }
813
814 if( !pCfg->ShortGI40MhzEnable )
815 {
816 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
817 }
818
819 if( !pCfg->nChannelBondingMode5GHz )
820 {
821 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
822 }
823
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530824 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530825 if (true == hdd_is_5g_supported(pHddCtx))
826 {
827 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
828 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530829
830 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
831 {
832
833 if (NULL == wiphy->bands[i])
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
836 __func__, i);
837 continue;
838 }
839
840 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
841 {
842 struct ieee80211_supported_band *band = wiphy->bands[i];
843
844 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
845 {
846 // Enable social channels for P2P
847 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
848 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
849 else
850 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
851 continue;
852 }
853 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
854 {
855 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
856 continue;
857 }
858 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 }
860 /*Initialise the supported cipher suite details*/
861 wiphy->cipher_suites = hdd_cipher_suites;
862 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
863
864 /*signal strength in mBm (100*dBm) */
865 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
866
867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 wiphy->max_remain_on_channel_duration = 1000;
869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700870
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800871 wiphy->n_vendor_commands = 0;
872 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
873 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
874
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530875 EXIT();
876 return 0;
877}
878
879/* In this function we are registering wiphy. */
880int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
881{
882 ENTER();
883 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 if (0 > wiphy_register(wiphy))
885 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530886 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
888 return -EIO;
889 }
890
891 EXIT();
892 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530893}
Jeff Johnson295189b2012-06-20 16:38:30 -0700894
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530895/* In this function we are updating channel list when,
896 regulatory domain is FCC and country code is US.
897 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
898 As per FCC smart phone is not a indoor device.
899 GO should not opeate on indoor channels */
900void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
901{
902 int j;
903 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
904 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
905 //Default counrtycode from NV at the time of wiphy initialization.
906 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
907 &defaultCountryCode[0]))
908 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700909 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 }
911 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
912 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530913 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
916 return;
917 }
918 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
919 {
920 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
921 // Mark UNII -1 band channel as passive
922 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
923 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
924 }
925 }
926}
927
Jeff Johnson295189b2012-06-20 16:38:30 -0700928/* In this function we will do all post VOS start initialization.
929 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530930 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700931*/
932void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
933{
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
935 /* Register for all P2P action, public action etc frames */
936 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
937
Jeff Johnsone7245742012-09-05 17:12:55 -0700938 ENTER();
939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /* Right now we are registering these frame when driver is getting
941 initialized. Once we will move to 2.6.37 kernel, in which we have
942 frame register ops, we will move this code as a part of that */
943 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
946
947 /* GAS Initial Response */
948 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
949 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530950
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 /* GAS Comeback Request */
952 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
953 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
954
955 /* GAS Comeback Response */
956 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
957 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
958
959 /* P2P Public Action */
960 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530961 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 P2P_PUBLIC_ACTION_FRAME_SIZE );
963
964 /* P2P Action */
965 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
966 (v_U8_t*)P2P_ACTION_FRAME,
967 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700968
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530969 /* WNM BSS Transition Request frame */
970 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
971 (v_U8_t*)WNM_BSS_ACTION_FRAME,
972 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700973
974 /* WNM-Notification */
975 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
976 (v_U8_t*)WNM_NOTIFICATION_FRAME,
977 WNM_NOTIFICATION_FRAME_SIZE );
978
979
980#ifdef WLAN_FEATURE_11W
981 /* SA Query Response Action Frame */
982 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
983 (v_U8_t*)SA_QUERY_FRAME_RSP,
984 SA_QUERY_FRAME_RSP_SIZE );
985#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700986}
987
988void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
989{
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
991 /* Register for all P2P action, public action etc frames */
992 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
993
Jeff Johnsone7245742012-09-05 17:12:55 -0700994 ENTER();
995
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 /* Right now we are registering these frame when driver is getting
997 initialized. Once we will move to 2.6.37 kernel, in which we have
998 frame register ops, we will move this code as a part of that */
999 /* GAS Initial Request */
1000
1001 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1002 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
1003
1004 /* GAS Initial Response */
1005 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1006 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301007
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 /* GAS Comeback Request */
1009 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1010 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
1011
1012 /* GAS Comeback Response */
1013 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1014 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
1015
1016 /* P2P Public Action */
1017 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301018 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001019 P2P_PUBLIC_ACTION_FRAME_SIZE );
1020
1021 /* P2P Action */
1022 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1023 (v_U8_t*)P2P_ACTION_FRAME,
1024 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07001025 /* WNM-Notification */
1026 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1027 (v_U8_t*)WNM_NOTIFICATION_FRAME,
1028 WNM_NOTIFICATION_FRAME_SIZE );
1029
Chet Lanctot186b5732013-03-18 10:26:30 -07001030
1031#ifdef WLAN_FEATURE_11W
1032 /* SA Query Response Action Frame */
1033 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1034 (v_U8_t*)SA_QUERY_FRAME_RSP,
1035 SA_QUERY_FRAME_RSP_SIZE );
1036#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001037}
1038
1039#ifdef FEATURE_WLAN_WAPI
1040void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1041 const u8 *mac_addr, u8 *key , int key_Len)
1042{
1043 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1044 tCsrRoamSetKey setKey;
1045 v_BOOL_t isConnected = TRUE;
1046 int status = 0;
1047 v_U32_t roamId= 0xFF;
1048 tANI_U8 *pKeyPtr = NULL;
1049 int n = 0;
1050
Arif Hussain6d2a3322013-11-17 19:50:10 -08001051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 __func__,pAdapter->device_mode);
1053
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301054 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 setKey.keyId = key_index; // Store Key ID
1056 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1057 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1058 setKey.paeRole = 0 ; // the PAE role
1059 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1060 {
1061 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1062 }
1063 else
1064 {
1065 isConnected = hdd_connIsConnected(pHddStaCtx);
1066 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1067 }
1068 setKey.keyLength = key_Len;
1069 pKeyPtr = setKey.Key;
1070 memcpy( pKeyPtr, key, key_Len);
1071
Arif Hussain6d2a3322013-11-17 19:50:10 -08001072 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001073 __func__, key_Len);
1074 for (n = 0 ; n < key_Len; n++)
1075 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1076 __func__,n,setKey.Key[n]);
1077
1078 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1079 if ( isConnected )
1080 {
1081 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1082 pAdapter->sessionId, &setKey, &roamId );
1083 }
1084 if ( status != 0 )
1085 {
1086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1087 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1088 __LINE__, status );
1089 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1090 }
1091}
1092#endif /* FEATURE_WLAN_WAPI*/
1093
1094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301095int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 beacon_data_t **ppBeacon,
1097 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001098#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301099int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001100 beacon_data_t **ppBeacon,
1101 struct cfg80211_beacon_data *params,
1102 int dtim_period)
1103#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301104{
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 int size;
1106 beacon_data_t *beacon = NULL;
1107 beacon_data_t *old = NULL;
1108 int head_len,tail_len;
1109
Jeff Johnsone7245742012-09-05 17:12:55 -07001110 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301112 {
1113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1114 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001115 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001117
1118 old = pAdapter->sessionCtx.ap.beacon;
1119
1120 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301121 {
1122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1123 FL("session(%d) old and new heads points to NULL"),
1124 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001125 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301126 }
1127
1128 if (params->tail && !params->tail_len)
1129 {
1130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1131 FL("tail_len is zero but tail is not NULL"));
1132 return -EINVAL;
1133 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001134
Jeff Johnson295189b2012-06-20 16:38:30 -07001135#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1136 /* Kernel 3.0 is not updating dtim_period for set beacon */
1137 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301138 {
1139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1140 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301142 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001143#endif
1144
1145 if(params->head)
1146 head_len = params->head_len;
1147 else
1148 head_len = old->head_len;
1149
1150 if(params->tail || !old)
1151 tail_len = params->tail_len;
1152 else
1153 tail_len = old->tail_len;
1154
1155 size = sizeof(beacon_data_t) + head_len + tail_len;
1156
1157 beacon = kzalloc(size, GFP_KERNEL);
1158
1159 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301160 {
1161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1162 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301164 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001165
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001166#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 if(params->dtim_period || !old )
1168 beacon->dtim_period = params->dtim_period;
1169 else
1170 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001171#else
1172 if(dtim_period || !old )
1173 beacon->dtim_period = dtim_period;
1174 else
1175 beacon->dtim_period = old->dtim_period;
1176#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301177
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1179 beacon->tail = beacon->head + head_len;
1180 beacon->head_len = head_len;
1181 beacon->tail_len = tail_len;
1182
1183 if(params->head) {
1184 memcpy (beacon->head,params->head,beacon->head_len);
1185 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301186 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001187 if(old)
1188 memcpy (beacon->head,old->head,beacon->head_len);
1189 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301190
Jeff Johnson295189b2012-06-20 16:38:30 -07001191 if(params->tail) {
1192 memcpy (beacon->tail,params->tail,beacon->tail_len);
1193 }
1194 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301195 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 memcpy (beacon->tail,old->tail,beacon->tail_len);
1197 }
1198
1199 *ppBeacon = beacon;
1200
1201 kfree(old);
1202
1203 return 0;
1204
1205}
Jeff Johnson295189b2012-06-20 16:38:30 -07001206
1207v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1208{
1209 int left = length;
1210 v_U8_t *ptr = pIes;
1211 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301212
Jeff Johnson295189b2012-06-20 16:38:30 -07001213 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301214 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 elem_id = ptr[0];
1216 elem_len = ptr[1];
1217 left -= 2;
1218 if(elem_len > left)
1219 {
1220 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001221 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001222 eid,elem_len,left);
1223 return NULL;
1224 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301225 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001226 {
1227 return ptr;
1228 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301229
Jeff Johnson295189b2012-06-20 16:38:30 -07001230 left -= elem_len;
1231 ptr += (elem_len + 2);
1232 }
1233 return NULL;
1234}
1235
Jeff Johnson295189b2012-06-20 16:38:30 -07001236/* Check if rate is 11g rate or not */
1237static int wlan_hdd_rate_is_11g(u8 rate)
1238{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001239 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 u8 i;
1241 for (i = 0; i < 8; i++)
1242 {
1243 if(rate == gRateArray[i])
1244 return TRUE;
1245 }
1246 return FALSE;
1247}
1248
1249/* Check for 11g rate and set proper 11g only mode */
1250static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1251 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1252{
1253 u8 i, num_rates = pIe[0];
1254
1255 pIe += 1;
1256 for ( i = 0; i < num_rates; i++)
1257 {
1258 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1259 {
1260 /* If rate set have 11g rate than change the mode to 11G */
1261 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1262 if (pIe[i] & BASIC_RATE_MASK)
1263 {
1264 /* If we have 11g rate as basic rate, it means mode
1265 is 11g only mode.
1266 */
1267 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1268 *pCheckRatesfor11g = FALSE;
1269 }
1270 }
1271 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1272 {
1273 *require_ht = TRUE;
1274 }
1275 }
1276 return;
1277}
1278
1279static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1280{
1281 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1282 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1283 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1284 u8 checkRatesfor11g = TRUE;
1285 u8 require_ht = FALSE;
1286 u8 *pIe=NULL;
1287
1288 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1289
1290 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1291 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1292 if (pIe != NULL)
1293 {
1294 pIe += 1;
1295 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1296 &pConfig->SapHw_mode);
1297 }
1298
1299 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1300 WLAN_EID_EXT_SUPP_RATES);
1301 if (pIe != NULL)
1302 {
1303
1304 pIe += 1;
1305 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1306 &pConfig->SapHw_mode);
1307 }
1308
1309 if( pConfig->channel > 14 )
1310 {
1311 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1312 }
1313
1314 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1315 WLAN_EID_HT_CAPABILITY);
1316
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301317 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001318 {
1319 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1320 if(require_ht)
1321 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1322 }
1323}
1324
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301325static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1326 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1327{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001328 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301329 v_U8_t *pIe = NULL;
1330 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1331
1332 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1333 pBeacon->tail, pBeacon->tail_len);
1334
1335 if (pIe)
1336 {
1337 ielen = pIe[1] + 2;
1338 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1339 {
1340 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1341 }
1342 else
1343 {
1344 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1345 return -EINVAL;
1346 }
1347 *total_ielen += ielen;
1348 }
1349 return 0;
1350}
1351
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001352static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1353 v_U8_t *genie, v_U8_t *total_ielen)
1354{
1355 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1356 int left = pBeacon->tail_len;
1357 v_U8_t *ptr = pBeacon->tail;
1358 v_U8_t elem_id, elem_len;
1359 v_U16_t ielen = 0;
1360
1361 if ( NULL == ptr || 0 == left )
1362 return;
1363
1364 while (left >= 2)
1365 {
1366 elem_id = ptr[0];
1367 elem_len = ptr[1];
1368 left -= 2;
1369 if (elem_len > left)
1370 {
1371 hddLog( VOS_TRACE_LEVEL_ERROR,
1372 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1373 elem_id, elem_len, left);
1374 return;
1375 }
1376 if (IE_EID_VENDOR == elem_id)
1377 {
1378 /* skipping the VSIE's which we don't want to include or
1379 * it will be included by existing code
1380 */
1381 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1382#ifdef WLAN_FEATURE_WFD
1383 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1384#endif
1385 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1386 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1387 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1388 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1389 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1390 {
1391 ielen = ptr[1] + 2;
1392 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1393 {
1394 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1395 *total_ielen += ielen;
1396 }
1397 else
1398 {
1399 hddLog( VOS_TRACE_LEVEL_ERROR,
1400 "IE Length is too big "
1401 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1402 elem_id, elem_len, *total_ielen);
1403 }
1404 }
1405 }
1406
1407 left -= elem_len;
1408 ptr += (elem_len + 2);
1409 }
1410 return;
1411}
1412
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001413#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001414static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1415 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001416#else
1417static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1418 struct cfg80211_beacon_data *params)
1419#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001420{
1421 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301422 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001423 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001424 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001425
1426 genie = vos_mem_malloc(MAX_GENIE_LEN);
1427
1428 if(genie == NULL) {
1429
1430 return -ENOMEM;
1431 }
1432
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301433 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1434 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301436 hddLog(LOGE,
1437 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301438 ret = -EINVAL;
1439 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 }
1441
1442#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301443 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1444 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1445 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301446 hddLog(LOGE,
1447 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301448 ret = -EINVAL;
1449 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001450 }
1451#endif
1452
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301453 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1454 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001455 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301456 hddLog(LOGE,
1457 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301458 ret = -EINVAL;
1459 goto done;
1460 }
1461
1462 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1463 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001464 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001466
1467 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1468 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1469 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1470 {
1471 hddLog(LOGE,
1472 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001473 ret = -EINVAL;
1474 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001475 }
1476
1477 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1478 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1479 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1480 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1481 ==eHAL_STATUS_FAILURE)
1482 {
1483 hddLog(LOGE,
1484 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001485 ret = -EINVAL;
1486 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 }
1488
1489 // Added for ProResp IE
1490 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1491 {
1492 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1493 u8 probe_rsp_ie_len[3] = {0};
1494 u8 counter = 0;
1495 /* Check Probe Resp Length if it is greater then 255 then Store
1496 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1497 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1498 Store More then 255 bytes into One Variable.
1499 */
1500 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1501 {
1502 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1503 {
1504 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1505 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1506 }
1507 else
1508 {
1509 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1510 rem_probe_resp_ie_len = 0;
1511 }
1512 }
1513
1514 rem_probe_resp_ie_len = 0;
1515
1516 if (probe_rsp_ie_len[0] > 0)
1517 {
1518 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1519 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1520 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1521 probe_rsp_ie_len[0], NULL,
1522 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1523 {
1524 hddLog(LOGE,
1525 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001526 ret = -EINVAL;
1527 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 }
1529 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1530 }
1531
1532 if (probe_rsp_ie_len[1] > 0)
1533 {
1534 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1535 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1536 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1537 probe_rsp_ie_len[1], NULL,
1538 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1539 {
1540 hddLog(LOGE,
1541 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001542 ret = -EINVAL;
1543 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001544 }
1545 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1546 }
1547
1548 if (probe_rsp_ie_len[2] > 0)
1549 {
1550 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1551 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1552 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1553 probe_rsp_ie_len[2], NULL,
1554 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1555 {
1556 hddLog(LOGE,
1557 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001558 ret = -EINVAL;
1559 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001560 }
1561 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1562 }
1563
1564 if (probe_rsp_ie_len[1] == 0 )
1565 {
1566 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1567 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1568 eANI_BOOLEAN_FALSE) )
1569 {
1570 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001571 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 }
1573 }
1574
1575 if (probe_rsp_ie_len[2] == 0 )
1576 {
1577 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1578 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1579 eANI_BOOLEAN_FALSE) )
1580 {
1581 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001582 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001583 }
1584 }
1585
1586 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1587 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1588 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1589 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1590 == eHAL_STATUS_FAILURE)
1591 {
1592 hddLog(LOGE,
1593 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001594 ret = -EINVAL;
1595 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 }
1597 }
1598 else
1599 {
1600 // Reset WNI_CFG_PROBE_RSP Flags
1601 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1602
1603 hddLog(VOS_TRACE_LEVEL_INFO,
1604 "%s: No Probe Response IE received in set beacon",
1605 __func__);
1606 }
1607
1608 // Added for AssocResp IE
1609 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1610 {
1611 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1612 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1613 params->assocresp_ies_len, NULL,
1614 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1615 {
1616 hddLog(LOGE,
1617 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001618 ret = -EINVAL;
1619 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001620 }
1621
1622 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1623 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1624 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1625 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1626 == eHAL_STATUS_FAILURE)
1627 {
1628 hddLog(LOGE,
1629 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001630 ret = -EINVAL;
1631 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 }
1633 }
1634 else
1635 {
1636 hddLog(VOS_TRACE_LEVEL_INFO,
1637 "%s: No Assoc Response IE received in set beacon",
1638 __func__);
1639
1640 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1641 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1642 eANI_BOOLEAN_FALSE) )
1643 {
1644 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001645 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001646 }
1647 }
1648
Jeff Johnsone7245742012-09-05 17:12:55 -07001649done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301651 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001652}
Jeff Johnson295189b2012-06-20 16:38:30 -07001653
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301654/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001655 * FUNCTION: wlan_hdd_validate_operation_channel
1656 * called by wlan_hdd_cfg80211_start_bss() and
1657 * wlan_hdd_cfg80211_set_channel()
1658 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301659 * channel list.
1660 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001661VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001662{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301663
Jeff Johnson295189b2012-06-20 16:38:30 -07001664 v_U32_t num_ch = 0;
1665 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1666 u32 indx = 0;
1667 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301668 v_U8_t fValidChannel = FALSE, count = 0;
1669 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301670
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1672
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301673 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001674 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301675 /* Validate the channel */
1676 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301678 if ( channel == rfChannels[count].channelNum )
1679 {
1680 fValidChannel = TRUE;
1681 break;
1682 }
1683 }
1684 if (fValidChannel != TRUE)
1685 {
1686 hddLog(VOS_TRACE_LEVEL_ERROR,
1687 "%s: Invalid Channel [%d]", __func__, channel);
1688 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001689 }
1690 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301691 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301693 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1694 valid_ch, &num_ch))
1695 {
1696 hddLog(VOS_TRACE_LEVEL_ERROR,
1697 "%s: failed to get valid channel list", __func__);
1698 return VOS_STATUS_E_FAILURE;
1699 }
1700 for (indx = 0; indx < num_ch; indx++)
1701 {
1702 if (channel == valid_ch[indx])
1703 {
1704 break;
1705 }
1706 }
1707
1708 if (indx >= num_ch)
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 "%s: Invalid Channel [%d]", __func__, channel);
1712 return VOS_STATUS_E_FAILURE;
1713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 }
1715 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301716
Jeff Johnson295189b2012-06-20 16:38:30 -07001717}
1718
Viral Modi3a32cc52013-02-08 11:14:52 -08001719/**
1720 * FUNCTION: wlan_hdd_cfg80211_set_channel
1721 * This function is used to set the channel number
1722 */
1723static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1724 struct ieee80211_channel *chan,
1725 enum nl80211_channel_type channel_type
1726 )
1727{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301728 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08001729 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001730 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001731 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301732 hdd_context_t *pHddCtx;
1733 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001734
1735 ENTER();
1736
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301737
Viral Modi3a32cc52013-02-08 11:14:52 -08001738 if( NULL == dev )
1739 {
1740 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001741 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001742 return -ENODEV;
1743 }
1744 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1745
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301746 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1747 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
1748 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08001749 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001750 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001751 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301752
1753 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1754 status = wlan_hdd_validate_context(pHddCtx);
1755
1756 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001757 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1759 "%s: HDD context is not valid", __func__);
1760 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001761 }
1762
1763 /*
1764 * Do freq to chan conversion
1765 * TODO: for 11a
1766 */
1767
1768 channel = ieee80211_frequency_to_channel(freq);
1769
1770 /* Check freq range */
1771 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1772 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1773 {
1774 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001775 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001776 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1777 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1778 return -EINVAL;
1779 }
1780
1781 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1782
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301783 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1784 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001785 {
1786 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1787 {
1788 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001789 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001790 return -EINVAL;
1791 }
1792 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1793 "%s: set channel to [%d] for device mode =%d",
1794 __func__, channel,pAdapter->device_mode);
1795 }
1796 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001797 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001798 )
1799 {
1800 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1801 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1803
1804 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1805 {
1806 /* Link is up then return cant set channel*/
1807 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001808 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001809 return -EINVAL;
1810 }
1811
1812 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1813 pHddStaCtx->conn_info.operationChannel = channel;
1814 pRoamProfile->ChannelInfo.ChannelList =
1815 &pHddStaCtx->conn_info.operationChannel;
1816 }
1817 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001818 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001819 )
1820 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301821 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1822 {
1823 if(VOS_STATUS_SUCCESS !=
1824 wlan_hdd_validate_operation_channel(pAdapter,channel))
1825 {
1826 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001827 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301828 return -EINVAL;
1829 }
1830 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1831 }
1832 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001833 {
1834 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1835
1836 /* If auto channel selection is configured as enable/ 1 then ignore
1837 channel set by supplicant
1838 */
1839 if ( cfg_param->apAutoChannelSelection )
1840 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301841 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1842 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001843 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1844 "%s: set channel to auto channel (0) for device mode =%d",
1845 __func__, pAdapter->device_mode);
1846 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301847 else
1848 {
1849 if(VOS_STATUS_SUCCESS !=
1850 wlan_hdd_validate_operation_channel(pAdapter,channel))
1851 {
1852 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001853 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301854 return -EINVAL;
1855 }
1856 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1857 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001858 }
1859 }
1860 else
1861 {
1862 hddLog(VOS_TRACE_LEVEL_FATAL,
1863 "%s: Invalid device mode failed to set valid channel", __func__);
1864 return -EINVAL;
1865 }
1866 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301867 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001868}
1869
Jeff Johnson295189b2012-06-20 16:38:30 -07001870#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1871static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1872 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001873#else
1874static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1875 struct cfg80211_beacon_data *params,
1876 const u8 *ssid, size_t ssid_len,
1877 enum nl80211_hidden_ssid hidden_ssid)
1878#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001879{
1880 tsap_Config_t *pConfig;
1881 beacon_data_t *pBeacon = NULL;
1882 struct ieee80211_mgmt *pMgmt_frame;
1883 v_U8_t *pIe=NULL;
1884 v_U16_t capab_info;
1885 eCsrAuthType RSNAuthType;
1886 eCsrEncryptionType RSNEncryptType;
1887 eCsrEncryptionType mcRSNEncryptType;
1888 int status = VOS_STATUS_SUCCESS;
1889 tpWLAN_SAPEventCB pSapEventCallback;
1890 hdd_hostapd_state_t *pHostapdState;
1891 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1892 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301893 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 struct qc_mac_acl_entry *acl_entry = NULL;
1895 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001896 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001897 v_BOOL_t MFPCapable;
1898 v_BOOL_t MFPRequired;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05301899 eHddDot11Mode sapDot11Mode =
1900 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001901
1902 ENTER();
1903
1904 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1905
1906 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1907
1908 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1909
1910 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1911
1912 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1913
1914 //channel is already set in the set_channel Call back
1915 //pConfig->channel = pCommitConfig->channel;
1916
1917 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301918 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1920
1921 pConfig->dtim_period = pBeacon->dtim_period;
1922
Arif Hussain6d2a3322013-11-17 19:50:10 -08001923 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001924 pConfig->dtim_period);
1925
1926
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001927 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001928 {
1929 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001930 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301931 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1932 {
1933 tANI_BOOLEAN restartNeeded;
1934 pConfig->ieee80211d = 1;
1935 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1936 sme_setRegInfo(hHal, pConfig->countryCode);
1937 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1938 }
1939 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001941 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001942 pConfig->ieee80211d = 1;
1943 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1944 sme_setRegInfo(hHal, pConfig->countryCode);
1945 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001947 else
1948 {
1949 pConfig->ieee80211d = 0;
1950 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301951 /*
1952 * If auto channel is configured i.e. channel is 0,
1953 * so skip channel validation.
1954 */
1955 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1956 {
1957 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1958 {
1959 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001960 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301961 return -EINVAL;
1962 }
1963 }
1964 else
1965 {
1966 if(1 != pHddCtx->is_dynamic_channel_range_set)
1967 {
1968 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1969 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1970 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1971 }
1972 pHddCtx->is_dynamic_channel_range_set = 0;
1973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001975 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001976 {
1977 pConfig->ieee80211d = 0;
1978 }
1979 pConfig->authType = eSAP_AUTO_SWITCH;
1980
1981 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301982
1983 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1985
1986 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1987
1988 /*Set wps station to configured*/
1989 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1990
1991 if(pIe)
1992 {
1993 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1994 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001995 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 return -EINVAL;
1997 }
1998 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1999 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002000 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 /* Check 15 bit of WPS IE as it contain information for wps state
2002 * WPS state
2003 */
2004 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
2005 {
2006 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
2007 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
2008 {
2009 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
2010 }
2011 }
2012 }
2013 else
2014 {
2015 pConfig->wps_state = SAP_WPS_DISABLED;
2016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302017 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07002018
2019 pConfig->RSNWPAReqIELength = 0;
2020 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302021 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 WLAN_EID_RSN);
2023 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302024 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002025 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2026 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2027 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302028 /* The actual processing may eventually be more extensive than
2029 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 * by the app.
2031 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302032 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2034 &RSNEncryptType,
2035 &mcRSNEncryptType,
2036 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002037 &MFPCapable,
2038 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002039 pConfig->pRSNWPAReqIE[1]+2,
2040 pConfig->pRSNWPAReqIE );
2041
2042 if( VOS_STATUS_SUCCESS == status )
2043 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302044 /* Now copy over all the security attributes you have
2045 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002046 * */
2047 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2048 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2049 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2050 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302051 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002052 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2054 }
2055 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302056
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2058 pBeacon->tail, pBeacon->tail_len);
2059
2060 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2061 {
2062 if (pConfig->pRSNWPAReqIE)
2063 {
2064 /*Mixed mode WPA/WPA2*/
2065 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2066 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2067 }
2068 else
2069 {
2070 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2071 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2072 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302073 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2075 &RSNEncryptType,
2076 &mcRSNEncryptType,
2077 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002078 &MFPCapable,
2079 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 pConfig->pRSNWPAReqIE[1]+2,
2081 pConfig->pRSNWPAReqIE );
2082
2083 if( VOS_STATUS_SUCCESS == status )
2084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302085 /* Now copy over all the security attributes you have
2086 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 * */
2088 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2089 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2090 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2091 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302092 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002093 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2095 }
2096 }
2097 }
2098
Jeff Johnson4416a782013-03-25 14:17:50 -07002099 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2100 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2101 return -EINVAL;
2102 }
2103
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2105
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002106#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 if (params->ssid != NULL)
2108 {
2109 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2110 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2111 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2112 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2113 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002114#else
2115 if (ssid != NULL)
2116 {
2117 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2118 pConfig->SSIDinfo.ssid.length = ssid_len;
2119 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2120 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2121 }
2122#endif
2123
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302124 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002125 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302126
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 /* default value */
2128 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2129 pConfig->num_accept_mac = 0;
2130 pConfig->num_deny_mac = 0;
2131
2132 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2133 pBeacon->tail, pBeacon->tail_len);
2134
2135 /* pIe for black list is following form:
2136 type : 1 byte
2137 length : 1 byte
2138 OUI : 4 bytes
2139 acl type : 1 byte
2140 no of mac addr in black list: 1 byte
2141 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302142 */
2143 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002144 {
2145 pConfig->SapMacaddr_acl = pIe[6];
2146 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002147 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002148 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302149 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2150 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2152 for (i = 0; i < pConfig->num_deny_mac; i++)
2153 {
2154 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2155 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 }
2158 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2159 pBeacon->tail, pBeacon->tail_len);
2160
2161 /* pIe for white list is following form:
2162 type : 1 byte
2163 length : 1 byte
2164 OUI : 4 bytes
2165 acl type : 1 byte
2166 no of mac addr in white list: 1 byte
2167 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302168 */
2169 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 {
2171 pConfig->SapMacaddr_acl = pIe[6];
2172 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002173 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002174 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302175 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2176 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002177 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2178 for (i = 0; i < pConfig->num_accept_mac; i++)
2179 {
2180 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2181 acl_entry++;
2182 }
2183 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302184
Jeff Johnson295189b2012-06-20 16:38:30 -07002185 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2186
Jeff Johnsone7245742012-09-05 17:12:55 -07002187#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002188 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302189 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2190 * 11ac in .ini and 11ac is supported by both host and firmware.
2191 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2192 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002193 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2194 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05302195 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
2196 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
2197 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
2198 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
2199 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 {
2201 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002202
2203 /* Disable VHT support in 2.4 GHz band */
2204 if (pConfig->channel <= 14 &&
2205 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2206 {
2207 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2208 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002209 }
2210#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302211
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002212 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2213 {
2214 sme_SelectCBMode(hHal,
2215 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2216 pConfig->channel);
2217 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 // ht_capab is not what the name conveys,this is used for protection bitmap
2219 pConfig->ht_capab =
2220 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2221
2222 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2223 {
2224 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2225 return -EINVAL;
2226 }
2227
2228 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302229 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002230 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2231 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302232 pConfig->obssProtEnabled =
2233 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002234
Chet Lanctot8cecea22014-02-11 19:09:36 -08002235#ifdef WLAN_FEATURE_11W
2236 pConfig->mfpCapable = MFPCapable;
2237 pConfig->mfpRequired = MFPRequired;
2238 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2239 pConfig->mfpCapable, pConfig->mfpRequired);
2240#endif
2241
Arif Hussain6d2a3322013-11-17 19:50:10 -08002242 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002244 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2245 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2246 (int)pConfig->channel);
2247 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2248 pConfig->SapHw_mode, pConfig->privacy,
2249 pConfig->authType);
2250 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2251 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2252 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2253 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002254
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302255 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 {
2257 //Bss already started. just return.
2258 //TODO Probably it should update some beacon params.
2259 hddLog( LOGE, "Bss Already started...Ignore the request");
2260 EXIT();
2261 return 0;
2262 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302263
Jeff Johnson295189b2012-06-20 16:38:30 -07002264 pConfig->persona = pHostapdAdapter->device_mode;
2265
2266 pSapEventCallback = hdd_hostapd_SAPEventCB;
2267 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2268 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2269 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002270 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 return -EINVAL;
2272 }
2273
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302274 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2276
2277 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302278
Jeff Johnson295189b2012-06-20 16:38:30 -07002279 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302280 {
2281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002282 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002283 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 VOS_ASSERT(0);
2285 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302286
Jeff Johnson295189b2012-06-20 16:38:30 -07002287 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2288
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002289#ifdef WLAN_FEATURE_P2P_DEBUG
2290 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2291 {
2292 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2293 {
2294 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2295 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002296 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002297 }
2298 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2299 {
2300 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2301 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002302 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002303 }
2304 }
2305#endif
2306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 pHostapdState->bCommit = TRUE;
2308 EXIT();
2309
2310 return 0;
2311}
2312
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002313#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302314static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2315 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002316 struct beacon_parameters *params)
2317{
2318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302319 hdd_context_t *pHddCtx;
2320 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002321
2322 ENTER();
2323
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302324 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2325 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
2326 pAdapter->sessionId, params->interval));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002327 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002328
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302329 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2330 status = wlan_hdd_validate_context(pHddCtx);
2331
2332 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002333 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2335 "%s: HDD context is not valid", __func__);
2336 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002337 }
2338
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302339 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002341 )
2342 {
2343 beacon_data_t *old,*new;
2344
2345 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302346
Jeff Johnson295189b2012-06-20 16:38:30 -07002347 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302348 {
2349 hddLog(VOS_TRACE_LEVEL_WARN,
2350 FL("already beacon info added to session(%d)"),
2351 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002352 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002354
2355 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2356
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302357 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002358 {
2359 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002360 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 return -EINVAL;
2362 }
2363
2364 pAdapter->sessionCtx.ap.beacon = new;
2365
2366 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2367 }
2368
2369 EXIT();
2370 return status;
2371}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302372
2373static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 struct net_device *dev,
2375 struct beacon_parameters *params)
2376{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302378 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302379 hdd_context_t *pHddCtx;
2380 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002381
2382 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2384 TRACE_CODE_HDD_CFG80211_SET_BEACON,
2385 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002387 __func__,pAdapter->device_mode);
2388
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2390 status = wlan_hdd_validate_context(pHddCtx);
2391
2392 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002393 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2395 "%s: HDD context is not valid", __func__);
2396 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002397 }
2398
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302399 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002400 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302401 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 {
2403 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302404
Jeff Johnson295189b2012-06-20 16:38:30 -07002405 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302406
Jeff Johnson295189b2012-06-20 16:38:30 -07002407 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302408 {
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 FL("session(%d) old and new heads points to NULL"),
2411 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002412 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002414
2415 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2416
2417 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302418 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002419 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 return -EINVAL;
2421 }
2422
2423 pAdapter->sessionCtx.ap.beacon = new;
2424
2425 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2426 }
2427
2428 EXIT();
2429 return status;
2430}
2431
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002432#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2433
2434#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002435static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2436 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002437#else
2438static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2439 struct net_device *dev)
2440#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002441{
2442 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002443 hdd_context_t *pHddCtx = NULL;
2444 hdd_scaninfo_t *pScanInfo = NULL;
2445 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302446 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002447
2448 ENTER();
2449
2450 if (NULL == pAdapter)
2451 {
2452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002453 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002454 return -ENODEV;
2455 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002456
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302457 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2458 TRACE_CODE_HDD_CFG80211_STOP_AP,
2459 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302460 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2461 status = wlan_hdd_validate_context(pHddCtx);
2462
2463 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002464 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 "%s: HDD context is not valid", __func__);
2467 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002468 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002469
2470 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2471 if (NULL == staAdapter)
2472 {
2473 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2474 if (NULL == staAdapter)
2475 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2477 "%s: HDD adapter context for STA/P2P-CLI is Null",
2478 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002479 }
2480 }
2481
2482 pScanInfo = &pHddCtx->scan_info;
2483
Arif Hussain6d2a3322013-11-17 19:50:10 -08002484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002485 __func__,pAdapter->device_mode);
2486
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002487 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002488 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302489 long ret;
2490
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002491 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302492 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2493 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302494 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002495 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002496 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302497 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002498 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302500 FL("Timeout occurred while waiting for abortscan %ld"),
2501 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002502
2503 if (pHddCtx->isLogpInProgress)
2504 {
2505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2506 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302507
2508 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002509 return -EAGAIN;
2510 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002511 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002512 }
2513 }
2514
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302515 hdd_hostapd_stop(dev);
2516
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002519 )
2520 {
2521 beacon_data_t *old;
2522
2523 old = pAdapter->sessionCtx.ap.beacon;
2524
2525 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302526 {
2527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2528 FL("session(%d) beacon data points to NULL"),
2529 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002532
Jeff Johnson295189b2012-06-20 16:38:30 -07002533 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002534
2535 mutex_lock(&pHddCtx->sap_lock);
2536 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2537 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002538 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002539 {
2540 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2541
2542 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2543
2544 if (!VOS_IS_STATUS_SUCCESS(status))
2545 {
2546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002547 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002548 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302549 }
2550 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002551 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2552 }
2553 mutex_unlock(&pHddCtx->sap_lock);
2554
2555 if(status != VOS_STATUS_SUCCESS)
2556 {
2557 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002558 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002559 return -EINVAL;
2560 }
2561
Jeff Johnson4416a782013-03-25 14:17:50 -07002562 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002563 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2564 ==eHAL_STATUS_FAILURE)
2565 {
2566 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002567 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002568 }
2569
Jeff Johnson4416a782013-03-25 14:17:50 -07002570 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002571 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2572 eANI_BOOLEAN_FALSE) )
2573 {
2574 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002575 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002576 }
2577
2578 // Reset WNI_CFG_PROBE_RSP Flags
2579 wlan_hdd_reset_prob_rspies(pAdapter);
2580
2581 pAdapter->sessionCtx.ap.beacon = NULL;
2582 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002583#ifdef WLAN_FEATURE_P2P_DEBUG
2584 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2585 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2586 {
2587 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2588 "GO got removed");
2589 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2590 }
2591#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002592 }
2593 EXIT();
2594 return status;
2595}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002596
2597#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2598
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302599static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2600 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002601 struct cfg80211_ap_settings *params)
2602{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302603 hdd_adapter_t *pAdapter;
2604 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302605 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002606
2607 ENTER();
2608
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302609 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002610 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302612 "%s: Device is Null", __func__);
2613 return -ENODEV;
2614 }
2615
2616 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2617 if (NULL == pAdapter)
2618 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302620 "%s: HDD adapter is Null", __func__);
2621 return -ENODEV;
2622 }
2623
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302624 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2625 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2626 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302627 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2628 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302630 "%s: HDD adapter magic is invalid", __func__);
2631 return -ENODEV;
2632 }
2633
2634 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302635 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302636
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302637 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302638 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2640 "%s: HDD context is not valid", __func__);
2641 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302642 }
2643
2644 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2645 __func__, pAdapter->device_mode);
2646
2647 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002648 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002649 )
2650 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302651 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002652
2653 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302654
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002655 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302656 {
2657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2658 FL("already beacon info added to session(%d)"),
2659 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002660 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302661 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002662
2663 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2664
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302665 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002666 {
2667 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302668 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002669 return -EINVAL;
2670 }
2671 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002673 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2674#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2675 params->channel, params->channel_type);
2676#else
2677 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2678#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002679#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002680 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2681 params->ssid_len, params->hidden_ssid);
2682 }
2683
2684 EXIT();
2685 return status;
2686}
2687
2688
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302689static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002690 struct net_device *dev,
2691 struct cfg80211_beacon_data *params)
2692{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302693 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302694 hdd_context_t *pHddCtx;
2695 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002696
2697 ENTER();
2698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2700 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2701 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002703 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302704
2705 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2706 status = wlan_hdd_validate_context(pHddCtx);
2707
2708 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002709 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2711 "%s: HDD context is not valid", __func__);
2712 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002713 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002714
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302715 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002716 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302717 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002718 {
2719 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302720
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002721 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302722
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002723 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302724 {
2725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2726 FL("session(%d) beacon data points to NULL"),
2727 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002728 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302729 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002730
2731 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2732
2733 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302734 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002735 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002736 return -EINVAL;
2737 }
2738
2739 pAdapter->sessionCtx.ap.beacon = new;
2740
2741 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2742 }
2743
2744 EXIT();
2745 return status;
2746}
2747
2748#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2749
Jeff Johnson295189b2012-06-20 16:38:30 -07002750
2751static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2752 struct net_device *dev,
2753 struct bss_parameters *params)
2754{
2755 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2756
2757 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302758
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302759 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2760 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2761 pAdapter->sessionId, params->ap_isolate));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002762 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002763 __func__,pAdapter->device_mode);
2764
2765 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002766 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302767 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002768 {
2769 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2770 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302771 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002772 {
2773 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302774 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002775 }
2776
2777 EXIT();
2778 return 0;
2779}
2780
Kiet Lam10841362013-11-01 11:36:50 +05302781/* FUNCTION: wlan_hdd_change_country_code_cd
2782* to wait for contry code completion
2783*/
2784void* wlan_hdd_change_country_code_cb(void *pAdapter)
2785{
2786 hdd_adapter_t *call_back_pAdapter = pAdapter;
2787 complete(&call_back_pAdapter->change_country_code);
2788 return NULL;
2789}
2790
Jeff Johnson295189b2012-06-20 16:38:30 -07002791/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302792 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002793 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2794 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302795int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002796 struct net_device *ndev,
2797 enum nl80211_iftype type,
2798 u32 *flags,
2799 struct vif_params *params
2800 )
2801{
2802 struct wireless_dev *wdev;
2803 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002804 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002805 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002806 tCsrRoamProfile *pRoamProfile = NULL;
2807 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302808 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002809 eMib_dot11DesiredBssType connectedBssType;
2810 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302811 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002812
2813 ENTER();
2814
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302815 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002816 {
2817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2818 "%s: Adapter context is null", __func__);
2819 return VOS_STATUS_E_FAILURE;
2820 }
2821
2822 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2823 if (!pHddCtx)
2824 {
2825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2826 "%s: HDD context is null", __func__);
2827 return VOS_STATUS_E_FAILURE;
2828 }
2829
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2831 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2832 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302833 status = wlan_hdd_validate_context(pHddCtx);
2834
2835 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2838 "%s: HDD context is not valid", __func__);
2839 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 }
2841
2842 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2843 __func__, pAdapter->device_mode);
2844
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302845 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002846 wdev = ndev->ieee80211_ptr;
2847
2848#ifdef WLAN_BTAMP_FEATURE
2849 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2850 (NL80211_IFTYPE_ADHOC == type)||
2851 (NL80211_IFTYPE_AP == type)||
2852 (NL80211_IFTYPE_P2P_GO == type))
2853 {
2854 pHddCtx->isAmpAllowed = VOS_FALSE;
2855 // stop AMP traffic
2856 status = WLANBAP_StopAmp();
2857 if(VOS_STATUS_SUCCESS != status )
2858 {
2859 pHddCtx->isAmpAllowed = VOS_TRUE;
2860 hddLog(VOS_TRACE_LEVEL_FATAL,
2861 "%s: Failed to stop AMP", __func__);
2862 return -EINVAL;
2863 }
2864 }
2865#endif //WLAN_BTAMP_FEATURE
2866 /* Reset the current device mode bit mask*/
2867 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2868
2869 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002870 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002871 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002872 )
2873 {
2874 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002875 if (!pWextState)
2876 {
2877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2878 "%s: pWextState is null", __func__);
2879 return VOS_STATUS_E_FAILURE;
2880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002881 pRoamProfile = &pWextState->roamProfile;
2882 LastBSSType = pRoamProfile->BSSType;
2883
2884 switch (type)
2885 {
2886 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002888 hddLog(VOS_TRACE_LEVEL_INFO,
2889 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2890 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002891#ifdef WLAN_FEATURE_11AC
2892 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2893 {
2894 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2895 }
2896#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302897 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002898 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002899 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002900 //Check for sub-string p2p to confirm its a p2p interface
2901 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302902 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002903 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2904 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2905 }
2906 else
2907 {
2908 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002910 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302911#ifdef FEATURE_WLAN_TDLS
2912 /* The open adapter for the p2p shall skip initializations in
2913 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2914 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2915 * tdls_init when the change_iface sets the device mode to
2916 * WLAN_HDD_P2P_CLIENT.
2917 */
2918
2919 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2920 {
2921 if (0 != wlan_hdd_tdls_init (pAdapter))
2922 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302923 hddLog(VOS_TRACE_LEVEL_ERROR,
2924 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302925 return -EINVAL;
2926 }
2927 }
2928#endif
2929
Jeff Johnson295189b2012-06-20 16:38:30 -07002930 break;
2931 case NL80211_IFTYPE_ADHOC:
2932 hddLog(VOS_TRACE_LEVEL_INFO,
2933 "%s: setting interface Type to ADHOC", __func__);
2934 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2935 pRoamProfile->phyMode =
2936 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002937 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 wdev->iftype = type;
2939 break;
2940
2941 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002942 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002943 {
2944 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2945 "%s: setting interface Type to %s", __func__,
2946 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2947
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002948 //Cancel any remain on channel for GO mode
2949 if (NL80211_IFTYPE_P2P_GO == type)
2950 {
2951 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2952 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002953 if (NL80211_IFTYPE_AP == type)
2954 {
2955 /* As Loading WLAN Driver one interface being created for p2p device
2956 * address. This will take one HW STA and the max number of clients
2957 * that can connect to softAP will be reduced by one. so while changing
2958 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2959 * interface as it is not required in SoftAP mode.
2960 */
2961
2962 // Get P2P Adapter
2963 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2964
2965 if (pP2pAdapter)
2966 {
2967 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2968 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2969 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2970 }
2971 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05302972 //Disable IMPS & BMPS for SAP/GO
2973 if(VOS_STATUS_E_FAILURE ==
2974 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2975 {
2976 //Fail to Exit BMPS
2977 VOS_ASSERT(0);
2978 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302979#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002980
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302981 /* A Mutex Lock is introduced while changing the mode to
2982 * protect the concurrent access for the Adapters by TDLS
2983 * module.
2984 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302985 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302986#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002987 //De-init the adapter.
2988 hdd_stop_adapter( pHddCtx, pAdapter );
2989 hdd_deinit_adapter( pHddCtx, pAdapter );
2990 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2992 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302993#ifdef FEATURE_WLAN_TDLS
2994 mutex_unlock(&pHddCtx->tdls_lock);
2995#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002996 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2997 (pConfig->apRandomBssidEnabled))
2998 {
2999 /* To meet Android requirements create a randomized
3000 MAC address of the form 02:1A:11:Fx:xx:xx */
3001 get_random_bytes(&ndev->dev_addr[3], 3);
3002 ndev->dev_addr[0] = 0x02;
3003 ndev->dev_addr[1] = 0x1A;
3004 ndev->dev_addr[2] = 0x11;
3005 ndev->dev_addr[3] |= 0xF0;
3006 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
3007 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08003008 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
3009 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003010 }
3011
Jeff Johnson295189b2012-06-20 16:38:30 -07003012 hdd_set_ap_ops( pAdapter->dev );
3013
Kiet Lam10841362013-11-01 11:36:50 +05303014 /* This is for only SAP mode where users can
3015 * control country through ini.
3016 * P2P GO follows station country code
3017 * acquired during the STA scanning. */
3018 if((NL80211_IFTYPE_AP == type) &&
3019 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3020 {
3021 int status = 0;
3022 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3023 "%s: setting country code from INI ", __func__);
3024 init_completion(&pAdapter->change_country_code);
3025 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3026 (void *)(tSmeChangeCountryCallback)
3027 wlan_hdd_change_country_code_cb,
3028 pConfig->apCntryCode, pAdapter,
3029 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303030 eSIR_FALSE,
3031 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303032 if (eHAL_STATUS_SUCCESS == status)
3033 {
3034 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303035 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303036 &pAdapter->change_country_code,
3037 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303038 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303039 {
3040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303041 FL("SME Timed out while setting country code %ld"),
3042 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003043
3044 if (pHddCtx->isLogpInProgress)
3045 {
3046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3047 "%s: LOGP in Progress. Ignore!!!", __func__);
3048 return -EAGAIN;
3049 }
Kiet Lam10841362013-11-01 11:36:50 +05303050 }
3051 }
3052 else
3053 {
3054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003055 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303056 return -EINVAL;
3057 }
3058 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003059 status = hdd_init_ap_mode(pAdapter);
3060 if(status != VOS_STATUS_SUCCESS)
3061 {
3062 hddLog(VOS_TRACE_LEVEL_FATAL,
3063 "%s: Error initializing the ap mode", __func__);
3064 return -EINVAL;
3065 }
3066 hdd_set_conparam(1);
3067
Jeff Johnson295189b2012-06-20 16:38:30 -07003068 /*interface type changed update in wiphy structure*/
3069 if(wdev)
3070 {
3071 wdev->iftype = type;
3072 pHddCtx->change_iface = type;
3073 }
3074 else
3075 {
3076 hddLog(VOS_TRACE_LEVEL_ERROR,
3077 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3078 return -EINVAL;
3079 }
3080 goto done;
3081 }
3082
3083 default:
3084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3085 __func__);
3086 return -EOPNOTSUPP;
3087 }
3088 }
3089 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003090 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003091 )
3092 {
3093 switch(type)
3094 {
3095 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003097 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303098#ifdef FEATURE_WLAN_TDLS
3099
3100 /* A Mutex Lock is introduced while changing the mode to
3101 * protect the concurrent access for the Adapters by TDLS
3102 * module.
3103 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303104 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303105#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003106 hdd_stop_adapter( pHddCtx, pAdapter );
3107 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003109 //Check for sub-string p2p to confirm its a p2p interface
3110 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003111 {
3112 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3113 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3114 }
3115 else
3116 {
3117 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003118 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003120 hdd_set_conparam(0);
3121 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003122 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3123 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303124#ifdef FEATURE_WLAN_TDLS
3125 mutex_unlock(&pHddCtx->tdls_lock);
3126#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303127 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003128 if( VOS_STATUS_SUCCESS != status )
3129 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003130 /* In case of JB, for P2P-GO, only change interface will be called,
3131 * This is the right place to enable back bmps_imps()
3132 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303133 if (pHddCtx->hdd_wlan_suspended)
3134 {
3135 hdd_set_pwrparams(pHddCtx);
3136 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003137 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003138 goto done;
3139 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003140 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003141 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003142 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3143 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003144 goto done;
3145 default:
3146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3147 __func__);
3148 return -EOPNOTSUPP;
3149
3150 }
3151
3152 }
3153 else
3154 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303155 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3156 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 return -EOPNOTSUPP;
3158 }
3159
3160
3161 if(pRoamProfile)
3162 {
3163 if ( LastBSSType != pRoamProfile->BSSType )
3164 {
3165 /*interface type changed update in wiphy structure*/
3166 wdev->iftype = type;
3167
3168 /*the BSS mode changed, We need to issue disconnect
3169 if connected or in IBSS disconnect state*/
3170 if ( hdd_connGetConnectedBssType(
3171 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3172 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3173 {
3174 /*need to issue a disconnect to CSR.*/
3175 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3176 if( eHAL_STATUS_SUCCESS ==
3177 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3178 pAdapter->sessionId,
3179 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3180 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303181 ret = wait_for_completion_interruptible_timeout(
3182 &pAdapter->disconnect_comp_var,
3183 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3184 if (ret <= 0)
3185 {
3186 hddLog(VOS_TRACE_LEVEL_ERROR,
3187 FL("wait on disconnect_comp_var failed %ld"), ret);
3188 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003189 }
3190 }
3191 }
3192 }
3193
3194done:
3195 /*set bitmask based on updated value*/
3196 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003197
3198 /* Only STA mode support TM now
3199 * all other mode, TM feature should be disabled */
3200 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3201 (~VOS_STA & pHddCtx->concurrency_mode) )
3202 {
3203 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3204 }
3205
Jeff Johnson295189b2012-06-20 16:38:30 -07003206#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303207 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003208 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3209 {
3210 //we are ok to do AMP
3211 pHddCtx->isAmpAllowed = VOS_TRUE;
3212 }
3213#endif //WLAN_BTAMP_FEATURE
3214 EXIT();
3215 return 0;
3216}
3217
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303218/*
3219 * FUNCTION: wlan_hdd_cfg80211_change_iface
3220 * wrapper function to protect the actual implementation from SSR.
3221 */
3222int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3223 struct net_device *ndev,
3224 enum nl80211_iftype type,
3225 u32 *flags,
3226 struct vif_params *params
3227 )
3228{
3229 int ret;
3230
3231 vos_ssr_protect(__func__);
3232 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3233 vos_ssr_unprotect(__func__);
3234
3235 return ret;
3236}
3237
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003238#ifdef FEATURE_WLAN_TDLS
3239static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3240 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3241{
3242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3243 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3244 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003245 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303246 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303247 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003248
3249 ENTER();
3250
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303251 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003252 {
3253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3254 "Invalid arguments");
3255 return -EINVAL;
3256 }
Hoonki Lee27511902013-03-14 18:19:06 -07003257
3258 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3259 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3260 {
3261 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3262 "%s: TDLS mode is disabled OR not enabled in FW."
3263 MAC_ADDRESS_STR " Request declined.",
3264 __func__, MAC_ADDR_ARRAY(mac));
3265 return -ENOTSUPP;
3266 }
3267
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003268 if (pHddCtx->isLogpInProgress)
3269 {
3270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3271 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003272 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003273 return -EBUSY;
3274 }
3275
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303276 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003277
3278 if ( NULL == pTdlsPeer ) {
3279 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3280 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3281 __func__, MAC_ADDR_ARRAY(mac), update);
3282 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003283 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003284
3285 /* in add station, we accept existing valid staId if there is */
3286 if ((0 == update) &&
3287 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3288 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003289 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003290 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003291 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003292 " link_status %d. staId %d. add station ignored.",
3293 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3294 return 0;
3295 }
3296 /* in change station, we accept only when staId is valid */
3297 if ((1 == update) &&
3298 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3299 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3300 {
3301 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3302 "%s: " MAC_ADDRESS_STR
3303 " link status %d. staId %d. change station %s.",
3304 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3305 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3306 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003307 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003308
3309 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303310 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003311 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3313 "%s: " MAC_ADDRESS_STR
3314 " TDLS setup is ongoing. Request declined.",
3315 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003316 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003317 }
3318
3319 /* first to check if we reached to maximum supported TDLS peer.
3320 TODO: for now, return -EPERM looks working fine,
3321 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303322 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3323 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003324 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3326 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303327 " TDLS Max peer already connected. Request declined."
3328 " Num of peers (%d), Max allowed (%d).",
3329 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3330 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003331 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003332 }
3333 else
3334 {
3335 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303336 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003337 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003338 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3340 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3341 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003342 return -EPERM;
3343 }
3344 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003345 if (0 == update)
3346 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003347
Jeff Johnsond75fe012013-04-06 10:53:06 -07003348 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303349 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003350 {
3351 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3352 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003353 if(StaParams->htcap_present)
3354 {
3355 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3356 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3357 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3358 "ht_capa->extended_capabilities: %0x",
3359 StaParams->HTCap.extendedHtCapInfo);
3360 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003361 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3362 "params->capability: %0x",StaParams->capability);
3363 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003364 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003365 if(StaParams->vhtcap_present)
3366 {
3367 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3368 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3369 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3370 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3371 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003372 {
3373 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003375 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3376 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3377 "[%d]: %x ", i, StaParams->supported_rates[i]);
3378 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003379 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303380 else if ((1 == update) && (NULL == StaParams))
3381 {
3382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3383 "%s : update is true, but staParams is NULL. Error!", __func__);
3384 return -EPERM;
3385 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003386
3387 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3388
3389 if (!update)
3390 {
3391 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3392 pAdapter->sessionId, mac);
3393 }
3394 else
3395 {
3396 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3397 pAdapter->sessionId, mac, StaParams);
3398 }
3399
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303400 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003401 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3402
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303403 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003404 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303406 "%s: timeout waiting for tdls add station indication %ld",
3407 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003408 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003409 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303410
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003411 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3412 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003414 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003415 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003416 }
3417
3418 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003419
3420error:
3421 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3422 return -EPERM;
3423
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003424}
3425#endif
3426
Jeff Johnson295189b2012-06-20 16:38:30 -07003427static int wlan_hdd_change_station(struct wiphy *wiphy,
3428 struct net_device *dev,
3429 u8 *mac,
3430 struct station_parameters *params)
3431{
3432 VOS_STATUS status = VOS_STATUS_SUCCESS;
3433 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303434 hdd_context_t *pHddCtx;
3435 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003436 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003437#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003438 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003439 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303440 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003441#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003442 ENTER();
3443
Gopichand Nakkala29149562013-05-10 21:43:41 +05303444 if ((NULL == pAdapter))
3445 {
3446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3447 "invalid adapter ");
3448 return -EINVAL;
3449 }
3450
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303451 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3452 TRACE_CODE_HDD_CHANGE_STATION,
3453 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303454 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3455 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3456
3457 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3458 {
3459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3460 "invalid HDD state or HDD station context");
3461 return -EINVAL;
3462 }
3463
3464 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003465 {
3466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3467 "%s:LOGP in Progress. Ignore!!!", __func__);
3468 return -EAGAIN;
3469 }
3470
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3472
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003473 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3474 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003475 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003476 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003477 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303478 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003479 WLANTL_STA_AUTHENTICATED);
3480
Gopichand Nakkala29149562013-05-10 21:43:41 +05303481 if (status != VOS_STATUS_SUCCESS)
3482 {
3483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3484 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3485 return -EINVAL;
3486 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003487 }
3488 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003489 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3490 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303491#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003492 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3493 StaParams.capability = params->capability;
3494 StaParams.uapsd_queues = params->uapsd_queues;
3495 StaParams.max_sp = params->max_sp;
3496
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303497 /* Convert (first channel , number of channels) tuple to
3498 * the total list of channels. This goes with the assumption
3499 * that if the first channel is < 14, then the next channels
3500 * are an incremental of 1 else an incremental of 4 till the number
3501 * of channels.
3502 */
3503 if (0 != params->supported_channels_len) {
3504 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3505 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3506 {
3507 int wifi_chan_index;
3508 StaParams.supported_channels[j] = params->supported_channels[i];
3509 wifi_chan_index =
3510 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3511 no_of_channels = params->supported_channels[i+1];
3512 for(k=1; k <= no_of_channels; k++)
3513 {
3514 StaParams.supported_channels[j+1] =
3515 StaParams.supported_channels[j] + wifi_chan_index;
3516 j+=1;
3517 }
3518 }
3519 StaParams.supported_channels_len = j;
3520 }
3521 vos_mem_copy(StaParams.supported_oper_classes,
3522 params->supported_oper_classes,
3523 params->supported_oper_classes_len);
3524 StaParams.supported_oper_classes_len =
3525 params->supported_oper_classes_len;
3526
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003527 if (0 != params->ext_capab_len)
3528 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3529 sizeof(StaParams.extn_capability));
3530
3531 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003532 {
3533 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003534 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003535 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003536
3537 StaParams.supported_rates_len = params->supported_rates_len;
3538
3539 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3540 * The supported_rates array , for all the structures propogating till Add Sta
3541 * to the firmware has to be modified , if the supplicant (ieee80211) is
3542 * modified to send more rates.
3543 */
3544
3545 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3546 */
3547 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3548 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3549
3550 if (0 != StaParams.supported_rates_len) {
3551 int i = 0;
3552 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3553 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003555 "Supported Rates with Length %d", StaParams.supported_rates_len);
3556 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003558 "[%d]: %0x", i, StaParams.supported_rates[i]);
3559 }
3560
3561 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003562 {
3563 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003564 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003565 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003566
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003567 if (0 != params->ext_capab_len ) {
3568 /*Define A Macro : TODO Sunil*/
3569 if ((1<<4) & StaParams.extn_capability[3]) {
3570 isBufSta = 1;
3571 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303572 /* TDLS Channel Switching Support */
3573 if ((1<<6) & StaParams.extn_capability[3]) {
3574 isOffChannelSupported = 1;
3575 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003576 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303577 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3578 &StaParams, isBufSta,
3579 isOffChannelSupported);
3580
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303581 if (VOS_STATUS_SUCCESS != status) {
3582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3583 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3584 return -EINVAL;
3585 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003586 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3587
3588 if (VOS_STATUS_SUCCESS != status) {
3589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3590 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3591 return -EINVAL;
3592 }
3593 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003594#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303595 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003596 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 return status;
3598}
3599
3600/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003601 * FUNCTION: wlan_hdd_cfg80211_add_key
3602 * This function is used to initialize the key information
3603 */
3604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003605static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003606 struct net_device *ndev,
3607 u8 key_index, bool pairwise,
3608 const u8 *mac_addr,
3609 struct key_params *params
3610 )
3611#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003612static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003613 struct net_device *ndev,
3614 u8 key_index, const u8 *mac_addr,
3615 struct key_params *params
3616 )
3617#endif
3618{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003620 tCsrRoamSetKey setKey;
3621 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303622 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003623 v_U32_t roamId= 0xFF;
3624 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003625 hdd_hostapd_state_t *pHostapdState;
3626 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003627 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303628 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003629
3630 ENTER();
3631
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3633 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3634 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303635 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3636 status = wlan_hdd_validate_context(pHddCtx);
3637
3638 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003639 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3641 "%s: HDD context is not valid", __func__);
3642 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003643 }
3644
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003645 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3646 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003647
3648 if (CSR_MAX_NUM_KEY <= key_index)
3649 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 key_index);
3652
3653 return -EINVAL;
3654 }
3655
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003656 if (CSR_MAX_KEY_LEN < params->key_len)
3657 {
3658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3659 params->key_len);
3660
3661 return -EINVAL;
3662 }
3663
3664 hddLog(VOS_TRACE_LEVEL_INFO,
3665 "%s: called with key index = %d & key length %d",
3666 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003667
3668 /*extract key idx, key len and key*/
3669 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3670 setKey.keyId = key_index;
3671 setKey.keyLength = params->key_len;
3672 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3673
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003674 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 {
3676 case WLAN_CIPHER_SUITE_WEP40:
3677 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3678 break;
3679
3680 case WLAN_CIPHER_SUITE_WEP104:
3681 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3682 break;
3683
3684 case WLAN_CIPHER_SUITE_TKIP:
3685 {
3686 u8 *pKey = &setKey.Key[0];
3687 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3688
3689 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3690
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003691 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003692
3693 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003694 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003695 |--------------|----------|----------|
3696 <---16bytes---><--8bytes--><--8bytes-->
3697
3698 */
3699 /*Sme expects the 32 bytes key to be in the below order
3700
3701 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003702 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003703 |--------------|----------|----------|
3704 <---16bytes---><--8bytes--><--8bytes-->
3705 */
3706 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003707 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003708
3709 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003710 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003711
3712 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003713 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003714
3715
3716 break;
3717 }
3718
3719 case WLAN_CIPHER_SUITE_CCMP:
3720 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3721 break;
3722
3723#ifdef FEATURE_WLAN_WAPI
3724 case WLAN_CIPHER_SUITE_SMS4:
3725 {
3726 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3727 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3728 params->key, params->key_len);
3729 return 0;
3730 }
3731#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003732
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003733#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003734 case WLAN_CIPHER_SUITE_KRK:
3735 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3736 break;
3737#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003738
3739#ifdef WLAN_FEATURE_11W
3740 case WLAN_CIPHER_SUITE_AES_CMAC:
3741 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003742 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003743#endif
3744
Jeff Johnson295189b2012-06-20 16:38:30 -07003745 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003747 __func__, params->cipher);
3748 return -EOPNOTSUPP;
3749 }
3750
3751 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3752 __func__, setKey.encType);
3753
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003754 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003755#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3756 (!pairwise)
3757#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003758 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003759#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003760 )
3761 {
3762 /* set group key*/
3763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3764 "%s- %d: setting Broadcast key",
3765 __func__, __LINE__);
3766 setKey.keyDirection = eSIR_RX_ONLY;
3767 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3768 }
3769 else
3770 {
3771 /* set pairwise key*/
3772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3773 "%s- %d: setting pairwise key",
3774 __func__, __LINE__);
3775 setKey.keyDirection = eSIR_TX_RX;
3776 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3777 }
3778 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3779 {
3780 setKey.keyDirection = eSIR_TX_RX;
3781 /*Set the group key*/
3782 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3783 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003784
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003785 if ( 0 != status )
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3789 return -EINVAL;
3790 }
3791 /*Save the keys here and call sme_RoamSetKey for setting
3792 the PTK after peer joins the IBSS network*/
3793 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3794 &setKey, sizeof(tCsrRoamSetKey));
3795 return status;
3796 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303797 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3798 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3799 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003800 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003801 if( pHostapdState->bssState == BSS_START )
3802 {
c_hpothu7c55da62014-01-23 18:34:02 +05303803 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3804 vos_status = wlan_hdd_check_ula_done(pAdapter);
3805
3806 if ( vos_status != VOS_STATUS_SUCCESS )
3807 {
3808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3809 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3810 __LINE__, vos_status );
3811
3812 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3813
3814 return -EINVAL;
3815 }
3816
Jeff Johnson295189b2012-06-20 16:38:30 -07003817 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3818
3819 if ( status != eHAL_STATUS_SUCCESS )
3820 {
3821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3822 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3823 __LINE__, status );
3824 }
3825 }
3826
3827 /* Saving WEP keys */
3828 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3829 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3830 {
3831 //Save the wep key in ap context. Issue setkey after the BSS is started.
3832 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3833 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3834 }
3835 else
3836 {
3837 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003838 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003839 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3840 }
3841 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003842 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3843 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003844 {
3845 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3846 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3847
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3849 if (!pairwise)
3850#else
3851 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3852#endif
3853 {
3854 /* set group key*/
3855 if (pHddStaCtx->roam_info.deferKeyComplete)
3856 {
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3858 "%s- %d: Perform Set key Complete",
3859 __func__, __LINE__);
3860 hdd_PerformRoamSetKeyComplete(pAdapter);
3861 }
3862 }
3863
Jeff Johnson295189b2012-06-20 16:38:30 -07003864 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3865
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003866 pWextState->roamProfile.Keys.defaultIndex = key_index;
3867
3868
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003869 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 params->key, params->key_len);
3871
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303872
Jeff Johnson295189b2012-06-20 16:38:30 -07003873 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3874
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303875 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003876 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303877 __func__, setKey.peerMac[0], setKey.peerMac[1],
3878 setKey.peerMac[2], setKey.peerMac[3],
3879 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003880 setKey.keyDirection);
3881
3882 vos_status = wlan_hdd_check_ula_done(pAdapter);
3883
3884 if ( vos_status != VOS_STATUS_SUCCESS )
3885 {
3886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3887 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3888 __LINE__, vos_status );
3889
3890 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3891
3892 return -EINVAL;
3893
3894 }
3895
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003896#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303897 /* The supplicant may attempt to set the PTK once pre-authentication
3898 is done. Save the key in the UMAC and include it in the ADD BSS
3899 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003900 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303901 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003902 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303903 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3904 "%s: Update PreAuth Key success", __func__);
3905 return 0;
3906 }
3907 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3908 {
3909 hddLog(VOS_TRACE_LEVEL_ERROR,
3910 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303911 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003912 }
3913#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003914
3915 /* issue set key request to SME*/
3916 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3917 pAdapter->sessionId, &setKey, &roamId );
3918
3919 if ( 0 != status )
3920 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303921 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3923 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3924 return -EINVAL;
3925 }
3926
3927
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303928 /* in case of IBSS as there was no information available about WEP keys during
3929 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303931 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3932 !( ( IW_AUTH_KEY_MGMT_802_1X
3933 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003934 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3935 )
3936 &&
3937 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3938 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3939 )
3940 )
3941 {
3942 setKey.keyDirection = eSIR_RX_ONLY;
3943 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3944
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303945 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003946 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303947 __func__, setKey.peerMac[0], setKey.peerMac[1],
3948 setKey.peerMac[2], setKey.peerMac[3],
3949 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003950 setKey.keyDirection);
3951
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303952 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003953 pAdapter->sessionId, &setKey, &roamId );
3954
3955 if ( 0 != status )
3956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303957 hddLog(VOS_TRACE_LEVEL_ERROR,
3958 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003959 __func__, status);
3960 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3961 return -EINVAL;
3962 }
3963 }
3964 }
3965
3966 return 0;
3967}
3968
3969/*
3970 * FUNCTION: wlan_hdd_cfg80211_get_key
3971 * This function is used to get the key information
3972 */
3973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303974static int wlan_hdd_cfg80211_get_key(
3975 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003976 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303977 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003978 const u8 *mac_addr, void *cookie,
3979 void (*callback)(void *cookie, struct key_params*)
3980 )
3981#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303982static int wlan_hdd_cfg80211_get_key(
3983 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 struct net_device *ndev,
3985 u8 key_index, const u8 *mac_addr, void *cookie,
3986 void (*callback)(void *cookie, struct key_params*)
3987 )
3988#endif
3989{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303990 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3992 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3993 struct key_params params;
3994
3995 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303996
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303997 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3998 TRACE_CODE_HDD_CFG80211_GET_KEY,
3999 pAdapter->sessionId, params.cipher));
Arif Hussain6d2a3322013-11-17 19:50:10 -08004000 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004001 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304002
Jeff Johnson295189b2012-06-20 16:38:30 -07004003 memset(&params, 0, sizeof(params));
4004
4005 if (CSR_MAX_NUM_KEY <= key_index)
4006 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304007 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304009 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004010
4011 switch(pRoamProfile->EncryptionType.encryptionType[0])
4012 {
4013 case eCSR_ENCRYPT_TYPE_NONE:
4014 params.cipher = IW_AUTH_CIPHER_NONE;
4015 break;
4016
4017 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4018 case eCSR_ENCRYPT_TYPE_WEP40:
4019 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4020 break;
4021
4022 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4023 case eCSR_ENCRYPT_TYPE_WEP104:
4024 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4025 break;
4026
4027 case eCSR_ENCRYPT_TYPE_TKIP:
4028 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4029 break;
4030
4031 case eCSR_ENCRYPT_TYPE_AES:
4032 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4033 break;
4034
4035 default:
4036 params.cipher = IW_AUTH_CIPHER_NONE;
4037 break;
4038 }
4039
4040 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4041 params.seq_len = 0;
4042 params.seq = NULL;
4043 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4044 callback(cookie, &params);
4045 return 0;
4046}
4047
4048/*
4049 * FUNCTION: wlan_hdd_cfg80211_del_key
4050 * This function is used to delete the key information
4051 */
4052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304053static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004054 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304055 u8 key_index,
4056 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004057 const u8 *mac_addr
4058 )
4059#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304060static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004061 struct net_device *ndev,
4062 u8 key_index,
4063 const u8 *mac_addr
4064 )
4065#endif
4066{
4067 int status = 0;
4068
4069 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304070 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004071 //it is observed that this is invalidating peer
4072 //key index whenever re-key is done. This is affecting data link.
4073 //It should be ok to ignore del_key.
4074#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4076 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004077 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4078 tCsrRoamSetKey setKey;
4079 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304080
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 ENTER();
4082
4083 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4084 __func__,pAdapter->device_mode);
4085
4086 if (CSR_MAX_NUM_KEY <= key_index)
4087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 key_index);
4090
4091 return -EINVAL;
4092 }
4093
4094 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4095 setKey.keyId = key_index;
4096
4097 if (mac_addr)
4098 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4099 else
4100 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4101
4102 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4103
4104 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004105 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304106 )
4107 {
4108
4109 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004110 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4111 if( pHostapdState->bssState == BSS_START)
4112 {
4113 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304114
Jeff Johnson295189b2012-06-20 16:38:30 -07004115 if ( status != eHAL_STATUS_SUCCESS )
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4119 __LINE__, status );
4120 }
4121 }
4122 }
4123 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304124 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004125 )
4126 {
4127 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4128
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304129 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4130
4131 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304133 __func__, setKey.peerMac[0], setKey.peerMac[1],
4134 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004135 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304136 if(pAdapter->sessionCtx.station.conn_info.connState ==
4137 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304139 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304141
Jeff Johnson295189b2012-06-20 16:38:30 -07004142 if ( 0 != status )
4143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304144 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004145 "%s: sme_RoamSetKey failure, returned %d",
4146 __func__, status);
4147 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4148 return -EINVAL;
4149 }
4150 }
4151 }
4152#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004153 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004154 return status;
4155}
4156
4157/*
4158 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4159 * This function is used to set the default tx key index
4160 */
4161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4162static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4163 struct net_device *ndev,
4164 u8 key_index,
4165 bool unicast, bool multicast)
4166#else
4167static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4168 struct net_device *ndev,
4169 u8 key_index)
4170#endif
4171{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304173 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304174 hdd_wext_state_t *pWextState;
4175 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304176 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004177
4178 ENTER();
4179
Gopichand Nakkala29149562013-05-10 21:43:41 +05304180 if ((NULL == pAdapter))
4181 {
4182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4183 "invalid adapter");
4184 return -EINVAL;
4185 }
4186
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304187 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4188 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4189 pAdapter->sessionId, key_index));
4190
Gopichand Nakkala29149562013-05-10 21:43:41 +05304191 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4193
4194 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4195 {
4196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4197 "invalid Wext state or HDD context");
4198 return -EINVAL;
4199 }
4200
Arif Hussain6d2a3322013-11-17 19:50:10 -08004201 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304203
Jeff Johnson295189b2012-06-20 16:38:30 -07004204 if (CSR_MAX_NUM_KEY <= key_index)
4205 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 key_index);
4208
4209 return -EINVAL;
4210 }
4211
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4213 status = wlan_hdd_validate_context(pHddCtx);
4214
4215 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4218 "%s: HDD context is not valid", __func__);
4219 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004220 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304221
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304224 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304226 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004227 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304228 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004229 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304231 {
4232 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304234
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 tCsrRoamSetKey setKey;
4236 v_U32_t roamId= 0xFF;
4237 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304238
4239 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004240 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304241
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 Keys->defaultIndex = (u8)key_index;
4243 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4244 setKey.keyId = key_index;
4245 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304246
4247 vos_mem_copy(&setKey.Key[0],
4248 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004249 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304250
Gopichand Nakkala29149562013-05-10 21:43:41 +05304251 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304252
4253 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004254 &pHddStaCtx->conn_info.bssId[0],
4255 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304256
Gopichand Nakkala29149562013-05-10 21:43:41 +05304257 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4258 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4259 eCSR_ENCRYPT_TYPE_WEP104)
4260 {
4261 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4262 even though ap is configured for WEP-40 encryption. In this canse the key length
4263 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4264 type(104) and switching encryption type to 40*/
4265 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4266 eCSR_ENCRYPT_TYPE_WEP40;
4267 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4268 eCSR_ENCRYPT_TYPE_WEP40;
4269 }
4270
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304271 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004272 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304273
Jeff Johnson295189b2012-06-20 16:38:30 -07004274 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304275 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004276 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304277
Jeff Johnson295189b2012-06-20 16:38:30 -07004278 if ( 0 != status )
4279 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304280 hddLog(VOS_TRACE_LEVEL_ERROR,
4281 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004282 status);
4283 return -EINVAL;
4284 }
4285 }
4286 }
4287
4288 /* In SoftAp mode setting key direction for default mode */
4289 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4290 {
4291 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4292 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4293 (eCSR_ENCRYPT_TYPE_AES !=
4294 pWextState->roamProfile.EncryptionType.encryptionType[0])
4295 )
4296 {
4297 /* Saving key direction for default key index to TX default */
4298 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4299 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4300 }
4301 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304302
Jeff Johnson295189b2012-06-20 16:38:30 -07004303 return status;
4304}
4305
Jeff Johnson295189b2012-06-20 16:38:30 -07004306/*
4307 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4308 * This function is used to inform the BSS details to nl80211 interface.
4309 */
4310static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4311 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4312{
4313 struct net_device *dev = pAdapter->dev;
4314 struct wireless_dev *wdev = dev->ieee80211_ptr;
4315 struct wiphy *wiphy = wdev->wiphy;
4316 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4317 int chan_no;
4318 int ie_length;
4319 const char *ie;
4320 unsigned int freq;
4321 struct ieee80211_channel *chan;
4322 int rssi = 0;
4323 struct cfg80211_bss *bss = NULL;
4324
4325 ENTER();
4326
4327 if( NULL == pBssDesc )
4328 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004329 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004330 return bss;
4331 }
4332
4333 chan_no = pBssDesc->channelId;
4334 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4335 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4336
4337 if( NULL == ie )
4338 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004339 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004340 return bss;
4341 }
4342
4343#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4344 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4345 {
4346 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4347 }
4348 else
4349 {
4350 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4351 }
4352#else
4353 freq = ieee80211_channel_to_frequency(chan_no);
4354#endif
4355
4356 chan = __ieee80211_get_channel(wiphy, freq);
4357
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304358 if (!chan) {
4359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4360 return NULL;
4361 }
4362
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4364 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4365 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4366 if (bss == NULL)
4367 {
4368 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4369
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304370 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4371 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 pBssDesc->capabilityInfo,
4373 pBssDesc->beaconInterval, ie, ie_length,
4374 rssi, GFP_KERNEL ));
4375}
4376 else
4377 {
4378 return bss;
4379 }
4380}
4381
4382
4383
4384/*
4385 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4386 * This function is used to inform the BSS details to nl80211 interface.
4387 */
4388struct cfg80211_bss*
4389wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4390 tSirBssDescription *bss_desc
4391 )
4392{
4393 /*
4394 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4395 already exists in bss data base of cfg80211 for that particular BSS ID.
4396 Using cfg80211_inform_bss_frame to update the bss entry instead of
4397 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4398 now there is no possibility to get the mgmt(probe response) frame from PE,
4399 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4400 cfg80211_inform_bss_frame.
4401 */
4402 struct net_device *dev = pAdapter->dev;
4403 struct wireless_dev *wdev = dev->ieee80211_ptr;
4404 struct wiphy *wiphy = wdev->wiphy;
4405 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004406#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4407 qcom_ie_age *qie_age = NULL;
4408 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4409#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004410 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004411#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 const char *ie =
4413 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4414 unsigned int freq;
4415 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304416 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004417 struct cfg80211_bss *bss_status = NULL;
4418 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4419 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004420 hdd_context_t *pHddCtx;
4421 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004422#ifdef WLAN_OPEN_SOURCE
4423 struct timespec ts;
4424#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004425
Wilson Yangf80a0542013-10-07 13:02:37 -07004426 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4427 status = wlan_hdd_validate_context(pHddCtx);
4428
4429 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304430 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004431 {
4432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4433 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4434 return NULL;
4435 }
4436
4437
4438 if (0 != status)
4439 {
4440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4441 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004442 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004443 }
4444
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304445 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004446 if (!mgmt)
4447 {
4448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4449 "%s: memory allocation failed ", __func__);
4450 return NULL;
4451 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004452
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004454
4455#ifdef WLAN_OPEN_SOURCE
4456 /* Android does not want the timestamp from the frame.
4457 Instead it wants a monotonic increasing value */
4458 get_monotonic_boottime(&ts);
4459 mgmt->u.probe_resp.timestamp =
4460 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4461#else
4462 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4464 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004465
4466#endif
4467
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4469 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004470
4471#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4472 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4473 /* Assuming this is the last IE, copy at the end */
4474 ie_length -=sizeof(qcom_ie_age);
4475 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4476 qie_age->element_id = QCOM_VENDOR_IE_ID;
4477 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4478 qie_age->oui_1 = QCOM_OUI1;
4479 qie_age->oui_2 = QCOM_OUI2;
4480 qie_age->oui_3 = QCOM_OUI3;
4481 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4482 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4483#endif
4484
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304486 if (bss_desc->fProbeRsp)
4487 {
4488 mgmt->frame_control |=
4489 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4490 }
4491 else
4492 {
4493 mgmt->frame_control |=
4494 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004496
4497#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304498 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004499 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4500 {
4501 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4502 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304503 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004504 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4505
4506 {
4507 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4508 }
4509 else
4510 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4512 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004513 kfree(mgmt);
4514 return NULL;
4515 }
4516#else
4517 freq = ieee80211_channel_to_frequency(chan_no);
4518#endif
4519 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004520 /*when the band is changed on the fly using the GUI, three things are done
4521 * 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)
4522 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4523 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4524 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4525 * and discards the channels correponding to previous band and calls back with zero bss results.
4526 * 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
4527 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4528 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4529 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4530 * So drop the bss and continue to next bss.
4531 */
4532 if(chan == NULL)
4533 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004535 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004536 return NULL;
4537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004538 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304539 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004540 * */
4541 if (( eConnectionState_Associated ==
4542 pAdapter->sessionCtx.station.conn_info.connState ) &&
4543 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4544 pAdapter->sessionCtx.station.conn_info.bssId,
4545 WNI_CFG_BSSID_LEN)))
4546 {
4547 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4548 rssi = (pAdapter->rssi * 100);
4549 }
4550 else
4551 {
4552 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4553 }
4554
Nirav Shah20ac06f2013-12-12 18:14:06 +05304555 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4556 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4557 chan->center_freq, (int)(rssi/100));
4558
Jeff Johnson295189b2012-06-20 16:38:30 -07004559 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4560 frame_len, rssi, GFP_KERNEL);
4561 kfree(mgmt);
4562 return bss_status;
4563}
4564
4565/*
4566 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4567 * This function is used to update the BSS data base of CFG8011
4568 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304569struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 tCsrRoamInfo *pRoamInfo
4571 )
4572{
4573 tCsrRoamConnectedProfile roamProfile;
4574 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4575 struct cfg80211_bss *bss = NULL;
4576
4577 ENTER();
4578
4579 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4580 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4581
4582 if (NULL != roamProfile.pBssDesc)
4583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304584 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004585 &roamProfile);
4586
4587 if (NULL == bss)
4588 {
4589 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4590 __func__);
4591 }
4592
4593 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4594 }
4595 else
4596 {
4597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4598 __func__);
4599 }
4600 return bss;
4601}
4602
4603/*
4604 * FUNCTION: wlan_hdd_cfg80211_update_bss
4605 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304606static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4607 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004608 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304609{
Jeff Johnson295189b2012-06-20 16:38:30 -07004610 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4611 tCsrScanResultInfo *pScanResult;
4612 eHalStatus status = 0;
4613 tScanResultHandle pResult;
4614 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004615 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004616
4617 ENTER();
4618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4620 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4621 NO_SESSION, pAdapter->sessionId));
4622
Wilson Yangf80a0542013-10-07 13:02:37 -07004623 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4624
4625 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004626 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4628 "%s:LOGP in Progress. Ignore!!!",__func__);
4629 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004630 }
4631
Wilson Yangf80a0542013-10-07 13:02:37 -07004632
4633 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304634 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004635 {
4636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4637 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4638 return VOS_STATUS_E_PERM;
4639 }
4640
4641
Jeff Johnson295189b2012-06-20 16:38:30 -07004642 /*
4643 * start getting scan results and populate cgf80211 BSS database
4644 */
4645 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4646
4647 /* no scan results */
4648 if (NULL == pResult)
4649 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4651 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004652 return status;
4653 }
4654
4655 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4656
4657 while (pScanResult)
4658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304659 /*
4660 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4661 * entry already exists in bss data base of cfg80211 for that
4662 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4663 * bss entry instead of cfg80211_inform_bss, But this call expects
4664 * mgmt packet as input. As of now there is no possibility to get
4665 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 * ieee80211_mgmt(probe response) and passing to c
4667 * fg80211_inform_bss_frame.
4668 * */
4669
4670 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4671 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304672
Jeff Johnson295189b2012-06-20 16:38:30 -07004673
4674 if (NULL == bss_status)
4675 {
4676 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004677 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 }
4679 else
4680 {
Yue Maf49ba872013-08-19 12:04:25 -07004681 cfg80211_put_bss(
4682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4683 wiphy,
4684#endif
4685 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004686 }
4687
4688 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4689 }
4690
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304691 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004692
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304693 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004694}
4695
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004696void
4697hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4698{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304699 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004700 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004701} /****** end hddPrintMacAddr() ******/
4702
4703void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004704hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004705{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304706 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004707 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004708 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4709 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4710 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004711} /****** end hddPrintPmkId() ******/
4712
4713//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4714//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4715
4716//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4717//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4718
4719#define dump_bssid(bssid) \
4720 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004721 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4722 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004723 }
4724
4725#define dump_pmkid(pMac, pmkid) \
4726 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004727 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4728 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004729 }
4730
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004731#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004732/*
4733 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4734 * This function is used to notify the supplicant of a new PMKSA candidate.
4735 */
4736int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304737 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004738 int index, bool preauth )
4739{
Jeff Johnsone7245742012-09-05 17:12:55 -07004740#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004741 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004742 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004743
4744 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004745 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004746
4747 if( NULL == pRoamInfo )
4748 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004749 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004750 return -EINVAL;
4751 }
4752
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004753 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4754 {
4755 dump_bssid(pRoamInfo->bssid);
4756 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004757 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004758 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004759#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304760 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004761}
4762#endif //FEATURE_WLAN_LFR
4763
Yue Maef608272013-04-08 23:09:17 -07004764#ifdef FEATURE_WLAN_LFR_METRICS
4765/*
4766 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4767 * 802.11r/LFR metrics reporting function to report preauth initiation
4768 *
4769 */
4770#define MAX_LFR_METRICS_EVENT_LENGTH 100
4771VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4772 tCsrRoamInfo *pRoamInfo)
4773{
4774 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4775 union iwreq_data wrqu;
4776
4777 ENTER();
4778
4779 if (NULL == pAdapter)
4780 {
4781 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4782 return VOS_STATUS_E_FAILURE;
4783 }
4784
4785 /* create the event */
4786 memset(&wrqu, 0, sizeof(wrqu));
4787 memset(metrics_notification, 0, sizeof(metrics_notification));
4788
4789 wrqu.data.pointer = metrics_notification;
4790 wrqu.data.length = scnprintf(metrics_notification,
4791 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4792 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4793
4794 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4795
4796 EXIT();
4797
4798 return VOS_STATUS_SUCCESS;
4799}
4800
4801/*
4802 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4803 * 802.11r/LFR metrics reporting function to report preauth completion
4804 * or failure
4805 */
4806VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4807 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4808{
4809 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4810 union iwreq_data wrqu;
4811
4812 ENTER();
4813
4814 if (NULL == pAdapter)
4815 {
4816 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4817 return VOS_STATUS_E_FAILURE;
4818 }
4819
4820 /* create the event */
4821 memset(&wrqu, 0, sizeof(wrqu));
4822 memset(metrics_notification, 0, sizeof(metrics_notification));
4823
4824 scnprintf(metrics_notification, sizeof(metrics_notification),
4825 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4826 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4827
4828 if (1 == preauth_status)
4829 strncat(metrics_notification, " TRUE", 5);
4830 else
4831 strncat(metrics_notification, " FALSE", 6);
4832
4833 wrqu.data.pointer = metrics_notification;
4834 wrqu.data.length = strlen(metrics_notification);
4835
4836 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4837
4838 EXIT();
4839
4840 return VOS_STATUS_SUCCESS;
4841}
4842
4843/*
4844 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4845 * 802.11r/LFR metrics reporting function to report handover initiation
4846 *
4847 */
4848VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4849 tCsrRoamInfo *pRoamInfo)
4850{
4851 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4852 union iwreq_data wrqu;
4853
4854 ENTER();
4855
4856 if (NULL == pAdapter)
4857 {
4858 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4859 return VOS_STATUS_E_FAILURE;
4860 }
4861
4862 /* create the event */
4863 memset(&wrqu, 0, sizeof(wrqu));
4864 memset(metrics_notification, 0, sizeof(metrics_notification));
4865
4866 wrqu.data.pointer = metrics_notification;
4867 wrqu.data.length = scnprintf(metrics_notification,
4868 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4869 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4870
4871 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4872
4873 EXIT();
4874
4875 return VOS_STATUS_SUCCESS;
4876}
4877#endif
4878
Jeff Johnson295189b2012-06-20 16:38:30 -07004879/*
4880 * FUNCTION: hdd_cfg80211_scan_done_callback
4881 * scanning callback function, called after finishing scan
4882 *
4883 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304884static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4886{
4887 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304888 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4891 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004892 struct cfg80211_scan_request *req = NULL;
4893 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304894 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304895 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004896
4897 ENTER();
4898
4899 hddLog(VOS_TRACE_LEVEL_INFO,
4900 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004901 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004902 __func__, halHandle, pContext, (int) scanId, (int) status);
4903
Kiet Lamac06e2c2013-10-23 16:25:07 +05304904 pScanInfo->mScanPendingCounter = 0;
4905
Jeff Johnson295189b2012-06-20 16:38:30 -07004906 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304907 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 &pScanInfo->scan_req_completion_event,
4909 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304910 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004911 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304912 hddLog(VOS_TRACE_LEVEL_ERROR,
4913 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004914 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004915 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004916 }
4917
Yue Maef608272013-04-08 23:09:17 -07004918 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004919 {
4920 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004921 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004922 }
4923
4924 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304925 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004926 {
4927 hddLog(VOS_TRACE_LEVEL_INFO,
4928 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004929 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004930 (int) scanId);
4931 }
4932
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304933 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 pAdapter);
4935
4936 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004938
4939
4940 /* If any client wait scan result through WEXT
4941 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004942 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004943 {
4944 /* The other scan request waiting for current scan finish
4945 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004946 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004947 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004948 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 }
4950 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004951 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 {
4953 struct net_device *dev = pAdapter->dev;
4954 union iwreq_data wrqu;
4955 int we_event;
4956 char *msg;
4957
4958 memset(&wrqu, '\0', sizeof(wrqu));
4959 we_event = SIOCGIWSCAN;
4960 msg = NULL;
4961 wireless_send_event(dev, we_event, &wrqu, msg);
4962 }
4963 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004964 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004965
4966 /* Get the Scan Req */
4967 req = pAdapter->request;
4968
4969 if (!req)
4970 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004971 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004972 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004973 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 }
4975
4976 /*
4977 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304978 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004979 req->n_ssids = 0;
4980 req->n_channels = 0;
4981 req->ie = 0;
4982
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004984 /* Scan is no longer pending */
4985 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004986
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004987 /*
4988 * cfg80211_scan_done informing NL80211 about completion
4989 * of scanning
4990 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304991 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
4992 {
4993 aborted = true;
4994 }
4995 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004996 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004997
Jeff Johnsone7245742012-09-05 17:12:55 -07004998allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004999 /* release the wake lock at the end of the scan*/
5000 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005001
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005002 /* Acquire wakelock to handle the case where APP's tries to suspend
5003 * immediatly after the driver gets connect request(i.e after scan)
5004 * from supplicant, this result in app's is suspending and not able
5005 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305006 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005007
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005008#ifdef FEATURE_WLAN_TDLS
5009 wlan_hdd_tdls_scan_done_callback(pAdapter);
5010#endif
5011
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 EXIT();
5013 return 0;
5014}
5015
5016/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005017 * FUNCTION: hdd_isScanAllowed
5018 * Go through each adapter and check if scan allowed
5019 *
5020 */
5021v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
5022{
5023 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5024 hdd_station_ctx_t *pHddStaCtx = NULL;
5025 hdd_adapter_t *pAdapter = NULL;
5026 VOS_STATUS status = 0;
5027 v_U8_t staId = 0;
5028 v_U8_t *staMac = NULL;
5029
c_hpothu9b781ba2013-12-30 20:57:45 +05305030 if (TRUE == pHddCtx->btCoexModeSet)
5031 {
5032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5033 FL("BTCoex Mode operation in progress, Do not allow scan"));
5034 return VOS_FALSE;
5035 }
5036
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005037 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5038
5039 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5040 {
5041 pAdapter = pAdapterNode->pAdapter;
5042
5043 if( pAdapter )
5044 {
5045 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305046 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005047 __func__, pAdapter->device_mode);
5048 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5049 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5050 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
5051 {
5052 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5053 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
5054 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
5055 {
5056 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5057 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005058 "%s: client " MAC_ADDRESS_STR
5059 " is in the middle of WPS/EAPOL exchange.", __func__,
5060 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005061 return VOS_FALSE;
5062 }
5063 }
5064 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5065 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5066 {
5067 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005070 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5071 {
5072 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5073
5074 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005075 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5076 "middle of WPS/EAPOL exchange.", __func__,
5077 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005078 return VOS_FALSE;
5079 }
5080 }
5081 }
5082 }
5083 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5084 pAdapterNode = pNext;
5085 }
5086 hddLog(VOS_TRACE_LEVEL_INFO,
5087 "%s: Scan allowed", __func__);
5088 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305089}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005090
5091/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 * FUNCTION: wlan_hdd_cfg80211_scan
5093 * this scan respond to scan trigger and update cfg80211 scan database
5094 * later, scan dump command can be used to recieve scan results
5095 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005096int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5097#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5098 struct net_device *dev,
5099#endif
5100 struct cfg80211_scan_request *request)
5101{
5102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5103 struct net_device *dev = request->wdev->netdev;
5104#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5107 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305108 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 tCsrScanRequest scanRequest;
5110 tANI_U8 *channelList = NULL, i;
5111 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305112 int status;
5113 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005115
5116 ENTER();
5117
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305118 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5119 TRACE_CODE_HDD_CFG80211_SCAN,
5120 pAdapter->sessionId, request->n_channels));
5121
Arif Hussain6d2a3322013-11-17 19:50:10 -08005122 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005124
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305125 status = wlan_hdd_validate_context(pHddCtx);
5126
5127 if (0 != status)
5128 {
5129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5130 "%s: HDD context is not valid", __func__);
5131 return status;
5132 }
5133
5134 cfg_param = pHddCtx->cfg_ini;
5135 pScanInfo = &pHddCtx->scan_info;
5136
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005137 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005138 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005139 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005140 {
5141 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005142 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5143 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005144 return -EBUSY;
5145 }
5146
Jeff Johnson295189b2012-06-20 16:38:30 -07005147#ifdef WLAN_BTAMP_FEATURE
5148 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005149 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005151 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 "%s: No scanning when AMP is on", __func__);
5153 return -EOPNOTSUPP;
5154 }
5155#endif
5156 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005157 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005159 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 "%s: Not scanning on device_mode = %d",
5161 __func__, pAdapter->device_mode);
5162 return -EOPNOTSUPP;
5163 }
5164
5165 if (TRUE == pScanInfo->mScanPending)
5166 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305167 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5168 {
5169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5170 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005171 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005172 }
5173
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305174 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005175 //Channel and action frame is pending
5176 //Otherwise Cancel Remain On Channel and allow Scan
5177 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005178 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005179 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305180 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005181 return -EBUSY;
5182 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005183#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005184 /* if tdls disagree scan right now, return immediately.
5185 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5186 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5187 */
5188 status = wlan_hdd_tdls_scan_callback (pAdapter,
5189 wiphy,
5190#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5191 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005192#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005193 request);
5194 if(status <= 0)
5195 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305196 if(!status)
5197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5198 "scan rejected %d", __func__, status);
5199 else
5200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5201 __func__, status);
5202
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005203 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005204 }
5205#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005206
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5208 {
5209 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005210 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305212 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5214 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305215 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005216 "%s: MAX TM Level Scan not allowed", __func__);
5217 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 }
5220 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5221
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005222 /* Check if scan is allowed at this point of time.
5223 */
5224 if (!hdd_isScanAllowed(pHddCtx))
5225 {
5226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5227 return -EBUSY;
5228 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305229
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5231
5232 if (NULL != request)
5233 {
5234 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305235 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005236
5237 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5238 * Becasue of this, driver is assuming that this is not wildcard scan and so
5239 * is not aging out the scan results.
5240 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005241 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 {
5243 request->n_ssids = 0;
5244 }
5245
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005246 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 {
5248 tCsrSSIDInfo *SsidInfo;
5249 int j;
5250 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5251 /* Allocate num_ssid tCsrSSIDInfo structure */
5252 SsidInfo = scanRequest.SSIDs.SSIDList =
5253 ( tCsrSSIDInfo *)vos_mem_malloc(
5254 request->n_ssids*sizeof(tCsrSSIDInfo));
5255
5256 if(NULL == scanRequest.SSIDs.SSIDList)
5257 {
5258 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305259 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005260 return -ENOMEM;
5261 }
5262
5263 /* copy all the ssid's and their length */
5264 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5265 {
5266 /* get the ssid length */
5267 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5268 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5269 SsidInfo->SSID.length);
5270 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305271 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005272 j, SsidInfo->SSID.ssId);
5273 }
5274 /* set the scan type to active */
5275 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5276 }
5277 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5278 {
5279 /* set the scan type to active */
5280 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5281 }
5282 else
5283 {
5284 /*Set the scan type to default type, in this case it is ACTIVE*/
5285 scanRequest.scanType = pScanInfo->scan_mode;
5286 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305287 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005288 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5289 }
5290 else
5291 {
5292 /* set the scan type to active */
5293 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5294 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5295
5296 /* set min and max channel time to zero */
5297 scanRequest.minChnTime = 0;
5298 scanRequest.maxChnTime = 0;
5299 }
5300
5301 /* set BSSType to default type */
5302 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5303
5304 /*TODO: scan the requested channels only*/
5305
5306 /*Right now scanning all the channels */
5307 if( request )
5308 {
c_hpothu53512302014-04-15 18:49:53 +05305309 if (MAX_CHANNEL < request->n_channels)
5310 {
5311 hddLog(VOS_TRACE_LEVEL_WARN,
5312 "No of Scan Channels exceeded limit: %d", request->n_channels);
5313 request->n_channels = MAX_CHANNEL;
5314 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305315 hddLog(VOS_TRACE_LEVEL_INFO,
5316 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305317
Jeff Johnson295189b2012-06-20 16:38:30 -07005318 if( request->n_channels )
5319 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305320 char chList [(request->n_channels*5)+1];
5321 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005322 channelList = vos_mem_malloc( request->n_channels );
5323 if( NULL == channelList )
5324 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305325 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305326 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 status = -ENOMEM;
5328 goto free_mem;
5329 }
5330
Nirav Shah20ac06f2013-12-12 18:14:06 +05305331 for( i = 0, len = 0; i < request->n_channels ; i++ )
5332 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305334 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5335 }
5336
5337 hddLog(VOS_TRACE_LEVEL_INFO,
5338 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005339 }
5340
5341 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5342 scanRequest.ChannelInfo.ChannelList = channelList;
5343
5344 /* set requestType to full scan */
5345 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305346
5347 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005348 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305349 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005350 */
5351
5352 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305353 * and in that case driver shoudnt flush scan results. If
5354 * driver flushes the scan results here and unfortunately if
5355 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005356 * fails which is not desired
5357 */
5358
5359 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5360 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305361 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005362 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5363 pAdapter->sessionId );
5364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005365
5366 if( request->ie_len )
5367 {
5368 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305369 /*TODO: Array needs to be converted to dynamic allocation,
5370 * as multiple ie.s can be sent in cfg80211_scan_request structure
5371 * CR 597966
5372 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005373 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5374 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5375 pScanInfo->scanAddIE.length = request->ie_len;
5376
Agarwal Ashish4f616132013-12-30 23:32:50 +05305377 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005378 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305379 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305381 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5382 {
5383 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5384 memcpy( pwextBuf->roamProfile.addIEScan,
5385 request->ie, request->ie_len);
5386 }
5387 else
5388 {
5389 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305390 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005392
Agarwal Ashish4f616132013-12-30 23:32:50 +05305393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005394 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5395 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5396
Jeff Johnson295189b2012-06-20 16:38:30 -07005397 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5398 request->ie_len);
5399 if (pP2pIe != NULL)
5400 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005401#ifdef WLAN_FEATURE_P2P_DEBUG
5402 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5403 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5404 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5405 {
5406 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5407 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5408 "Go nego completed to Connection is started");
5409 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5410 "for 8way Handshake");
5411 }
5412 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5413 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5414 {
5415 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5416 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5417 "Disconnected state to Connection is started");
5418 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5419 "for 4way Handshake");
5420 }
5421#endif
5422
Jeff Johnsone7245742012-09-05 17:12:55 -07005423 /* no_cck will be set during p2p find to disable 11b rates */
5424 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 hddLog(VOS_TRACE_LEVEL_INFO,
5427 "%s: This is a P2P Search", __func__);
5428 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005429
Jeff Johnsone7245742012-09-05 17:12:55 -07005430 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5431 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005432 /* set requestType to P2P Discovery */
5433 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005434 }
5435
5436 /*
5437 Skip Dfs Channel in case of P2P Search
5438 if it is set in ini file
5439 */
5440 if(cfg_param->skipDfsChnlInP2pSearch)
5441 {
5442 scanRequest.skipDfsChnlInP2pSearch = 1;
5443 }
5444 else
5445 {
5446 scanRequest.skipDfsChnlInP2pSearch = 0;
5447 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005448
Jeff Johnson295189b2012-06-20 16:38:30 -07005449 }
5450 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 }
5452 }
5453
5454 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5455
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005456 /* acquire the wakelock to avoid the apps suspend during the scan. To
5457 * address the following issues.
5458 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5459 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5460 * for long time, this result in apps running at full power for long time.
5461 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5462 * be stuck in full power because of resume BMPS
5463 */
5464 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005465
Nirav Shah20ac06f2013-12-12 18:14:06 +05305466 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5467 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5468 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5469 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5470 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5471
Jeff Johnsone7245742012-09-05 17:12:55 -07005472 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 pAdapter->sessionId, &scanRequest, &scanId,
5474 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005475
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 if (eHAL_STATUS_SUCCESS != status)
5477 {
5478 hddLog(VOS_TRACE_LEVEL_ERROR,
5479 "%s: sme_ScanRequest returned error %d", __func__, status);
5480 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005481 if(eHAL_STATUS_RESOURCES == status)
5482 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5484 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005485 status = -EBUSY;
5486 } else {
5487 status = -EIO;
5488 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005489 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 goto free_mem;
5491 }
5492
5493 pScanInfo->mScanPending = TRUE;
5494 pAdapter->request = request;
5495 pScanInfo->scanId = scanId;
5496
5497 complete(&pScanInfo->scan_req_completion_event);
5498
5499free_mem:
5500 if( scanRequest.SSIDs.SSIDList )
5501 {
5502 vos_mem_free(scanRequest.SSIDs.SSIDList);
5503 }
5504
5505 if( channelList )
5506 vos_mem_free( channelList );
5507
5508 EXIT();
5509
5510 return status;
5511}
5512
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005513
5514void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5515{
5516 v_U8_t iniDot11Mode =
5517 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5518 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5519
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305520 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5521 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005522 switch ( iniDot11Mode )
5523 {
5524 case eHDD_DOT11_MODE_AUTO:
5525 case eHDD_DOT11_MODE_11ac:
5526 case eHDD_DOT11_MODE_11ac_ONLY:
5527#ifdef WLAN_FEATURE_11AC
5528 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5529#else
5530 hddDot11Mode = eHDD_DOT11_MODE_11n;
5531#endif
5532 break;
5533 case eHDD_DOT11_MODE_11n:
5534 case eHDD_DOT11_MODE_11n_ONLY:
5535 hddDot11Mode = eHDD_DOT11_MODE_11n;
5536 break;
5537 default:
5538 hddDot11Mode = iniDot11Mode;
5539 break;
5540 }
5541 /* This call decides required channel bonding mode */
5542 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5543 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5544 operationChannel);
5545}
5546
Jeff Johnson295189b2012-06-20 16:38:30 -07005547/*
5548 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305549 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305551int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005552 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005553{
5554 int status = 0;
5555 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005556 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 v_U32_t roamId;
5558 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005559 eCsrAuthType RSNAuthType;
5560
5561 ENTER();
5562
5563 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005564 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5565
5566 status = wlan_hdd_validate_context(pHddCtx);
5567 if (status)
5568 {
5569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5570 "%s: HDD context is not valid!", __func__);
5571 return status;
5572 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305573
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5575 {
5576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5577 return -EINVAL;
5578 }
5579
5580 pRoamProfile = &pWextState->roamProfile;
5581
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305582 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005584 hdd_station_ctx_t *pHddStaCtx;
5585 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005586
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5589 {
5590 /*QoS not enabled in cfg file*/
5591 pRoamProfile->uapsd_mask = 0;
5592 }
5593 else
5594 {
5595 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305596 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5598 }
5599
5600 pRoamProfile->SSIDs.numOfSSIDs = 1;
5601 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5602 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305603 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5605 ssid, ssid_len);
5606
5607 if (bssid)
5608 {
5609 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5610 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5611 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305612 /* Save BSSID in seperate variable as well, as RoamProfile
5613 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 case of join failure we should send valid BSSID to supplicant
5615 */
5616 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5617 WNI_CFG_BSSID_LEN);
5618 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005619 else
5620 {
5621 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005623
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305624 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5625 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5627 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305628 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 /*set gen ie*/
5630 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5631 /*set auth*/
5632 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005634#ifdef FEATURE_WLAN_WAPI
5635 if (pAdapter->wapi_info.nWapiMode)
5636 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005637 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 switch (pAdapter->wapi_info.wapiAuthMode)
5639 {
5640 case WAPI_AUTH_MODE_PSK:
5641 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005642 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 pAdapter->wapi_info.wapiAuthMode);
5644 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5645 break;
5646 }
5647 case WAPI_AUTH_MODE_CERT:
5648 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005649 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 pAdapter->wapi_info.wapiAuthMode);
5651 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5652 break;
5653 }
5654 } // End of switch
5655 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5656 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5657 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005658 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 pRoamProfile->AuthType.numEntries = 1;
5660 pRoamProfile->EncryptionType.numEntries = 1;
5661 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5662 pRoamProfile->mcEncryptionType.numEntries = 1;
5663 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5664 }
5665 }
5666#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305667#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305668 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305669 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5670 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5671 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305672 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5673 sizeof (tSirGtkOffloadParams));
5674 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305675 }
5676#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005677 pRoamProfile->csrPersona = pAdapter->device_mode;
5678
Jeff Johnson32d95a32012-09-10 13:15:23 -07005679 if( operatingChannel )
5680 {
5681 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5682 pRoamProfile->ChannelInfo.numOfChannels = 1;
5683 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005684 else
5685 {
5686 pRoamProfile->ChannelInfo.ChannelList = NULL;
5687 pRoamProfile->ChannelInfo.numOfChannels = 0;
5688 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005689 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5690 {
5691 hdd_select_cbmode(pAdapter,operatingChannel);
5692 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305693
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005694 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5695 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305696 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005697 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005698 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5699 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305700 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5701 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005702 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5703 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305704
5705 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 pAdapter->sessionId, pRoamProfile, &roamId);
5707
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305708 if ((eHAL_STATUS_SUCCESS != status) &&
5709 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5710 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305711
5712 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5714 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5715 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305716 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005717 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305718 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005719
5720 pRoamProfile->ChannelInfo.ChannelList = NULL;
5721 pRoamProfile->ChannelInfo.numOfChannels = 0;
5722
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 }
5724 else
5725 {
5726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5727 return -EINVAL;
5728 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005729 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 return status;
5731}
5732
5733/*
5734 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5735 * This function is used to set the authentication type (OPEN/SHARED).
5736 *
5737 */
5738static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5739 enum nl80211_auth_type auth_type)
5740{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5743
5744 ENTER();
5745
5746 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305747 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305750 hddLog(VOS_TRACE_LEVEL_INFO,
5751 "%s: set authentication type to AUTOSWITCH", __func__);
5752 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5753 break;
5754
5755 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005756#ifdef WLAN_FEATURE_VOWIFI_11R
5757 case NL80211_AUTHTYPE_FT:
5758#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305759 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 "%s: set authentication type to OPEN", __func__);
5761 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5762 break;
5763
5764 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305765 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 "%s: set authentication type to SHARED", __func__);
5767 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5768 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005769#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305771 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 "%s: set authentication type to CCKM WPA", __func__);
5773 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5774 break;
5775#endif
5776
5777
5778 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305779 hddLog(VOS_TRACE_LEVEL_ERROR,
5780 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 auth_type);
5782 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5783 return -EINVAL;
5784 }
5785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 pHddStaCtx->conn_info.authType;
5788 return 0;
5789}
5790
5791/*
5792 * FUNCTION: wlan_hdd_set_akm_suite
5793 * This function is used to set the key mgmt type(PSK/8021x).
5794 *
5795 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 u32 key_mgmt
5798 )
5799{
5800 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5801 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305802
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 /*set key mgmt type*/
5804 switch(key_mgmt)
5805 {
5806 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305807#ifdef WLAN_FEATURE_VOWIFI_11R
5808 case WLAN_AKM_SUITE_FT_PSK:
5809#endif
5810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 __func__);
5812 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5813 break;
5814
5815 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305816#ifdef WLAN_FEATURE_VOWIFI_11R
5817 case WLAN_AKM_SUITE_FT_8021X:
5818#endif
5819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 __func__);
5821 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5822 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005823#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005824#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5825#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5826 case WLAN_AKM_SUITE_CCKM:
5827 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5828 __func__);
5829 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5830 break;
5831#endif
5832
5833 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 __func__, key_mgmt);
5836 return -EINVAL;
5837
5838 }
5839 return 0;
5840}
5841
5842/*
5843 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305844 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 * (NONE/WEP40/WEP104/TKIP/CCMP).
5846 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305847static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5848 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005849 bool ucast
5850 )
5851{
5852 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305853 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5855
5856 ENTER();
5857
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305858 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 __func__, cipher);
5862 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5863 }
5864 else
5865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305868 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 {
5870 case IW_AUTH_CIPHER_NONE:
5871 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5872 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305873
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305875 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305877
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305879 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305881
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 case WLAN_CIPHER_SUITE_TKIP:
5883 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5884 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 case WLAN_CIPHER_SUITE_CCMP:
5887 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5888 break;
5889#ifdef FEATURE_WLAN_WAPI
5890 case WLAN_CIPHER_SUITE_SMS4:
5891 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5892 break;
5893#endif
5894
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005895#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 case WLAN_CIPHER_SUITE_KRK:
5897 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5898 break;
5899#endif
5900 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 __func__, cipher);
5903 return -EOPNOTSUPP;
5904 }
5905 }
5906
5907 if (ucast)
5908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 __func__, encryptionType);
5911 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5912 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305913 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 encryptionType;
5915 }
5916 else
5917 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305918 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 __func__, encryptionType);
5920 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5921 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5922 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5923 }
5924
5925 return 0;
5926}
5927
5928
5929/*
5930 * FUNCTION: wlan_hdd_cfg80211_set_ie
5931 * This function is used to parse WPA/RSN IE's.
5932 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305933int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5934 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 size_t ie_len
5936 )
5937{
5938 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5939 u8 *genie = ie;
5940 v_U16_t remLen = ie_len;
5941#ifdef FEATURE_WLAN_WAPI
5942 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5943 u16 *tmp;
5944 v_U16_t akmsuiteCount;
5945 int *akmlist;
5946#endif
5947 ENTER();
5948
5949 /* clear previous assocAddIE */
5950 pWextState->assocAddIE.length = 0;
5951 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07005952 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005953
5954 while (remLen >= 2)
5955 {
5956 v_U16_t eLen = 0;
5957 v_U8_t elementId;
5958 elementId = *genie++;
5959 eLen = *genie++;
5960 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961
Arif Hussain6d2a3322013-11-17 19:50:10 -08005962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305964
5965 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305967 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005968 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 -07005969 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305970 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 "%s: Invalid WPA IE", __func__);
5972 return -EINVAL;
5973 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305974 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 {
5976 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305979
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5981 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005982 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5983 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 VOS_ASSERT(0);
5985 return -ENOMEM;
5986 }
5987 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5988 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5989 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5992 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5993 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5994 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305995 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5996 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5998 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5999 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6000 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6001 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6002 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306003 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306004 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 {
6006 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6011 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006012 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6013 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 VOS_ASSERT(0);
6015 return -ENOMEM;
6016 }
6017 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6018 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6019 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306020
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6022 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006024#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306025 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6026 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 /*Consider WFD IE, only for P2P Client */
6028 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6029 {
6030 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306031 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306033
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6035 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006036 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6037 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 VOS_ASSERT(0);
6039 return -ENOMEM;
6040 }
6041 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6042 // WPS IE + P2P IE + WFD IE
6043 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6044 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306045
Jeff Johnson295189b2012-06-20 16:38:30 -07006046 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6047 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6048 }
6049#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006050 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306051 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006052 HS20_OUI_TYPE_SIZE)) )
6053 {
6054 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306055 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006056 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006057
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006058 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6059 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006060 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6061 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006062 VOS_ASSERT(0);
6063 return -ENOMEM;
6064 }
6065 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6066 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006067
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006068 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6069 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6070 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006071 /* Appending OSEN Information Element in Assiciation Request */
6072 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6073 OSEN_OUI_TYPE_SIZE)) )
6074 {
6075 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6076 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6077 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006078
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006079 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6080 {
6081 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6082 "Need bigger buffer space");
6083 VOS_ASSERT(0);
6084 return -ENOMEM;
6085 }
6086 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6087 pWextState->assocAddIE.length += eLen + 2;
6088
6089 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6090 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6091 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6092 }
6093
6094 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006095 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6096
6097 /* populating as ADDIE in beacon frames */
6098 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6099 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6100 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6101 {
6102 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6103 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6104 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6105 {
6106 hddLog(LOGE,
6107 "Coldn't pass "
6108 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6109 }
6110 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6111 else
6112 hddLog(LOGE,
6113 "Could not pass on "
6114 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6115
6116 /* IBSS mode doesn't contain params->proberesp_ies still
6117 beaconIE's need to be populated in probe response frames */
6118 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6119 {
6120 u16 rem_probe_resp_ie_len = eLen + 2;
6121 u8 probe_rsp_ie_len[3] = {0};
6122 u8 counter = 0;
6123
6124 /* Check Probe Resp Length if it is greater then 255 then
6125 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6126 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6127 not able Store More then 255 bytes into One Variable */
6128
6129 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6130 {
6131 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6132 {
6133 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6134 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6135 }
6136 else
6137 {
6138 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6139 rem_probe_resp_ie_len = 0;
6140 }
6141 }
6142
6143 rem_probe_resp_ie_len = 0;
6144
6145 if (probe_rsp_ie_len[0] > 0)
6146 {
6147 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6148 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6149 (tANI_U8*)(genie - 2),
6150 probe_rsp_ie_len[0], NULL,
6151 eANI_BOOLEAN_FALSE)
6152 == eHAL_STATUS_FAILURE)
6153 {
6154 hddLog(LOGE,
6155 "Could not pass"
6156 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6157 }
6158 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6159 }
6160
6161 if (probe_rsp_ie_len[1] > 0)
6162 {
6163 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6164 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6165 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6166 probe_rsp_ie_len[1], NULL,
6167 eANI_BOOLEAN_FALSE)
6168 == eHAL_STATUS_FAILURE)
6169 {
6170 hddLog(LOGE,
6171 "Could not pass"
6172 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6173 }
6174 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6175 }
6176
6177 if (probe_rsp_ie_len[2] > 0)
6178 {
6179 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6180 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6181 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6182 probe_rsp_ie_len[2], NULL,
6183 eANI_BOOLEAN_FALSE)
6184 == eHAL_STATUS_FAILURE)
6185 {
6186 hddLog(LOGE,
6187 "Could not pass"
6188 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6189 }
6190 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6191 }
6192
6193 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6194 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6195 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6196 {
6197 hddLog(LOGE,
6198 "Could not pass"
6199 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6200 }
6201 }
6202 else
6203 {
6204 // Reset WNI_CFG_PROBE_RSP Flags
6205 wlan_hdd_reset_prob_rspies(pAdapter);
6206
6207 hddLog(VOS_TRACE_LEVEL_INFO,
6208 "%s: No Probe Response IE received in set beacon",
6209 __func__);
6210 }
6211 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 break;
6213 case DOT11F_EID_RSN:
6214 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6215 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6216 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6217 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6218 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6219 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006220 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6221 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306222 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006223 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006225 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306226
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006227 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6228 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006229 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6230 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006231 VOS_ASSERT(0);
6232 return -ENOMEM;
6233 }
6234 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6235 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306236
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006237 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6238 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6239 break;
6240 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006241#ifdef FEATURE_WLAN_WAPI
6242 case WLAN_EID_WAPI:
6243 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006244 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 pAdapter->wapi_info.nWapiMode);
6246 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306247 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 akmsuiteCount = WPA_GET_LE16(tmp);
6249 tmp = tmp + 1;
6250 akmlist = (int *)(tmp);
6251 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6252 {
6253 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6254 }
6255 else
6256 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006257 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 VOS_ASSERT(0);
6259 return -EINVAL;
6260 }
6261
6262 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6263 {
6264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006265 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306269 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006271 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6273 }
6274 break;
6275#endif
6276 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306277 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006279 /* when Unknown IE is received we should break and continue
6280 * to the next IE in the buffer instead we were returning
6281 * so changing this to break */
6282 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 }
6284 genie += eLen;
6285 remLen -= eLen;
6286 }
6287 EXIT();
6288 return 0;
6289}
6290
6291/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306292 * FUNCTION: hdd_isWPAIEPresent
6293 * Parse the received IE to find the WPA IE
6294 *
6295 */
6296static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6297{
6298 v_U8_t eLen = 0;
6299 v_U16_t remLen = ie_len;
6300 v_U8_t elementId = 0;
6301
6302 while (remLen >= 2)
6303 {
6304 elementId = *ie++;
6305 eLen = *ie++;
6306 remLen -= 2;
6307 if (eLen > remLen)
6308 {
6309 hddLog(VOS_TRACE_LEVEL_ERROR,
6310 "%s: IE length is wrong %d", __func__, eLen);
6311 return FALSE;
6312 }
6313 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6314 {
6315 /* OUI - 0x00 0X50 0XF2
6316 WPA Information Element - 0x01
6317 WPA version - 0x01*/
6318 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6319 return TRUE;
6320 }
6321 ie += eLen;
6322 remLen -= eLen;
6323 }
6324 return FALSE;
6325}
6326
6327/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306329 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 * parameters during connect operation.
6331 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306332int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 struct cfg80211_connect_params *req
6334 )
6335{
6336 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 ENTER();
6339
6340 /*set wpa version*/
6341 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6342
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306343 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306345 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 {
6347 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6348 }
6349 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6350 {
6351 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6352 }
6353 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306354
6355 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 pWextState->wpaVersion);
6357
6358 /*set authentication type*/
6359 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6360
6361 if (0 > status)
6362 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306363 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 "%s: failed to set authentication type ", __func__);
6365 return status;
6366 }
6367
6368 /*set key mgmt type*/
6369 if (req->crypto.n_akm_suites)
6370 {
6371 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6372 if (0 > status)
6373 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 __func__);
6376 return status;
6377 }
6378 }
6379
6380 /*set pairwise cipher type*/
6381 if (req->crypto.n_ciphers_pairwise)
6382 {
6383 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6384 req->crypto.ciphers_pairwise[0], true);
6385 if (0 > status)
6386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306387 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 "%s: failed to set unicast cipher type", __func__);
6389 return status;
6390 }
6391 }
6392 else
6393 {
6394 /*Reset previous cipher suite to none*/
6395 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6396 if (0 > status)
6397 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306398 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 "%s: failed to set unicast cipher type", __func__);
6400 return status;
6401 }
6402 }
6403
6404 /*set group cipher type*/
6405 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6406 false);
6407
6408 if (0 > status)
6409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 __func__);
6412 return status;
6413 }
6414
Chet Lanctot186b5732013-03-18 10:26:30 -07006415#ifdef WLAN_FEATURE_11W
6416 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6417#endif
6418
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6420 if (req->ie_len)
6421 {
6422 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6423 if ( 0 > status)
6424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 __func__);
6427 return status;
6428 }
6429 }
6430
6431 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306432 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 {
6434 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6435 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6436 )
6437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306438 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306441 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 __func__);
6443 return -EOPNOTSUPP;
6444 }
6445 else
6446 {
6447 u8 key_len = req->key_len;
6448 u8 key_idx = req->key_idx;
6449
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306450 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 && (CSR_MAX_NUM_KEY > key_idx)
6452 )
6453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306454 hddLog(VOS_TRACE_LEVEL_INFO,
6455 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 __func__, key_idx, key_len);
6457 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306460 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 (u8)key_len;
6462 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6463 }
6464 }
6465 }
6466 }
6467
6468 return status;
6469}
6470
6471/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306472 * FUNCTION: wlan_hdd_try_disconnect
6473 * This function is used to disconnect from previous
6474 * connection
6475 */
6476static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6477{
6478 long ret = 0;
6479 hdd_station_ctx_t *pHddStaCtx;
6480 eMib_dot11DesiredBssType connectedBssType;
6481
6482 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6483
6484 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6485
6486 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6487 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6488 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6489 {
6490 /* Issue disconnect to CSR */
6491 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6492 if( eHAL_STATUS_SUCCESS ==
6493 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6494 pAdapter->sessionId,
6495 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6496 {
6497 ret = wait_for_completion_interruptible_timeout(
6498 &pAdapter->disconnect_comp_var,
6499 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6500 if (0 >= ret)
6501 {
6502 hddLog(LOGE, FL("Failed to receive disconnect event"));
6503 return -EALREADY;
6504 }
6505 }
6506 }
6507 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6508 {
6509 ret = wait_for_completion_interruptible_timeout(
6510 &pAdapter->disconnect_comp_var,
6511 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6512 if (0 >= ret)
6513 {
6514 hddLog(LOGE, FL("Failed to receive disconnect event"));
6515 return -EALREADY;
6516 }
6517 }
6518
6519 return 0;
6520}
6521
6522/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306524 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 * parameters during connect operation.
6526 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306527static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 struct net_device *ndev,
6529 struct cfg80211_connect_params *req
6530 )
6531{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306532 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306533 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006535 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006536
6537 ENTER();
6538
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306539 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6540 TRACE_CODE_HDD_CFG80211_CONNECT,
6541 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306542 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006543 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006544
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306545 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006546 if (!pHddCtx)
6547 {
6548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6549 "%s: HDD context is null", __func__);
6550 return VOS_STATUS_E_FAILURE;
6551 }
6552
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306553 status = wlan_hdd_validate_context(pHddCtx);
6554
6555 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6558 "%s: HDD context is not valid", __func__);
6559 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 }
6561
6562#ifdef WLAN_BTAMP_FEATURE
6563 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306564 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306566 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006568 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 }
6570#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306571
6572 //If Device Mode is Station Concurrent Sessions Exit BMps
6573 //P2P Mode will be taken care in Open/close adapter
6574 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6575 (vos_concurrent_sessions_running()))
6576 {
6577 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6578 }
6579
6580 /*Try disconnecting if already in connected state*/
6581 status = wlan_hdd_try_disconnect(pAdapter);
6582 if ( 0 > status)
6583 {
6584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6585 " connection"));
6586 return -EALREADY;
6587 }
6588
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306590 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006591
6592 if ( 0 > status)
6593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 __func__);
6596 return status;
6597 }
6598
Mohit Khanna765234a2012-09-11 15:08:35 -07006599 if ( req->channel )
6600 {
6601 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6602 req->ssid_len, req->bssid,
6603 req->channel->hw_value);
6604 }
6605 else
6606 {
6607 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306608 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006609 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006610
6611 if (0 > status)
6612 {
6613 //ReEnable BMPS if disabled
6614 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6615 (NULL != pHddCtx))
6616 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306617 if (pHddCtx->hdd_wlan_suspended)
6618 {
6619 hdd_set_pwrparams(pHddCtx);
6620 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 //ReEnable Bmps and Imps back
6622 hdd_enable_bmps_imps(pHddCtx);
6623 }
6624
6625 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6626 return status;
6627 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306628 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 EXIT();
6630 return status;
6631}
6632
6633
6634/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306635 * FUNCTION: wlan_hdd_disconnect
6636 * This function is used to issue a disconnect request to SME
6637 */
6638int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6639{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306640 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306641 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306642 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6643
6644 status = wlan_hdd_validate_context(pHddCtx);
6645
6646 if (0 != status)
6647 {
6648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6649 "%s: HDD context is not valid", __func__);
6650 return status;
6651 }
6652
6653 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306654 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306655 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306656
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306657 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306658
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306659 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6660 pAdapter->sessionId, reason);
6661
6662 if ( 0 != status )
6663 {
6664 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006665 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306666 __func__, (int)status );
6667 return -EINVAL;
6668 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306669 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306670 &pAdapter->disconnect_comp_var,
6671 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306672 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306673 {
6674 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306675 "%s: Failed to disconnect, timed out", __func__);
6676 return -ETIMEDOUT;
6677 }
6678 else if (status == -ERESTARTSYS)
6679 {
6680 hddLog(VOS_TRACE_LEVEL_ERROR,
6681 "%s: Failed to disconnect, wait interrupted", __func__);
6682 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306683 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306684 /*stop tx queues*/
6685 netif_tx_disable(pAdapter->dev);
6686 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306687 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306688}
6689
6690
6691/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 * FUNCTION: wlan_hdd_cfg80211_disconnect
6693 * This function is used to issue a disconnect request to SME
6694 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306695static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006696 struct net_device *dev,
6697 u16 reason
6698 )
6699{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306700 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6701 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306703 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006705 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306706#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006707 tANI_U8 staIdx;
6708#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306709
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306711
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306712 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6713 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6714 pAdapter->sessionId, reason));
6715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 __func__,pAdapter->device_mode);
6717
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306718 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6719 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006720
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306721 status = wlan_hdd_validate_context(pHddCtx);
6722
6723 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6726 "%s: HDD context is not valid", __func__);
6727 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006728 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306729
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 if (NULL != pRoamProfile)
6731 {
6732 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306733 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6734 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306736 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306738 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 switch(reason)
6740 {
6741 case WLAN_REASON_MIC_FAILURE:
6742 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6743 break;
6744
6745 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6746 case WLAN_REASON_DISASSOC_AP_BUSY:
6747 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6748 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6749 break;
6750
6751 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6752 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6753 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6754 break;
6755
6756 case WLAN_REASON_DEAUTH_LEAVING:
6757 default:
6758 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6759 break;
6760 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306761 pScanInfo = &pHddCtx->scan_info;
6762 if (pScanInfo->mScanPending)
6763 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306764 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306765 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306766 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6767 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306768 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006769
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006770#ifdef FEATURE_WLAN_TDLS
6771 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006772 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006773 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006774 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6775 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006776 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006777 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006778 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006779 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006780 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006781 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006782 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006783 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006784 pAdapter->sessionId,
6785 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006786 }
6787 }
6788#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306789 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306790 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6791 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 {
6793 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006794 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 __func__, (int)status );
6796 return -EINVAL;
6797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306799 else
6800 {
6801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6802 "called while in %d state", __func__,
6803 pHddStaCtx->conn_info.connState);
6804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 }
6806 else
6807 {
6808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6809 }
6810
6811 return status;
6812}
6813
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306814
Jeff Johnson295189b2012-06-20 16:38:30 -07006815/*
6816 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306817 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 * settings in IBSS mode.
6819 */
6820static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306821 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 struct cfg80211_ibss_params *params
6823 )
6824{
6825 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6828 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306829
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 ENTER();
6831
6832 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006833 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006834
6835 if (params->ie_len && ( NULL != params->ie) )
6836 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006837 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6838 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006839 {
6840 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6841 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6842 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006843 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006845 tDot11fIEWPA dot11WPAIE;
6846 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006847 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006848
Wilson Yang00256342013-10-10 23:13:38 -07006849 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006850 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6851 params->ie_len, DOT11F_EID_WPA);
6852 if ( NULL != ie )
6853 {
6854 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6855 // Unpack the WPA IE
6856 //Skip past the EID byte and length byte - and four byte WiFi OUI
6857 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6858 &ie[2+4],
6859 ie[1] - 4,
6860 &dot11WPAIE);
6861 /*Extract the multicast cipher, the encType for unicast
6862 cipher for wpa-none is none*/
6863 encryptionType =
6864 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006867
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6869
6870 if (0 > status)
6871 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 __func__);
6874 return status;
6875 }
6876 }
6877
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306878 pWextState->roamProfile.AuthType.authType[0] =
6879 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006880 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6881
6882 if (params->privacy)
6883 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306884 /* Security enabled IBSS, At this time there is no information available
6885 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306887 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306889 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006890 *enable privacy bit in beacons */
6891
6892 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6893 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006894 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6895 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6897 pWextState->roamProfile.EncryptionType.numEntries = 1;
6898 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 return status;
6900}
6901
6902/*
6903 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306904 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 struct net_device *dev,
6908 struct cfg80211_ibss_params *params
6909 )
6910{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6913 tCsrRoamProfile *pRoamProfile;
6914 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006915 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306917 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006918
6919 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6922 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
6923 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006925 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006926
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306927 status = wlan_hdd_validate_context(pHddCtx);
6928
6929 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6932 "%s: HDD context is not valid", __func__);
6933 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 }
6935
6936 if (NULL == pWextState)
6937 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006938 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 __func__);
6940 return -EIO;
6941 }
6942
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306943 /*Try disconnecting if already in connected state*/
6944 status = wlan_hdd_try_disconnect(pAdapter);
6945 if ( 0 > status)
6946 {
6947 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6948 " IBSS connection"));
6949 return -EALREADY;
6950 }
6951
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 pRoamProfile = &pWextState->roamProfile;
6953
6954 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306956 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006957 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 return -EINVAL;
6959 }
6960
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006961 /* BSSID is provided by upper layers hence no need to AUTO generate */
6962 if (NULL != params->bssid) {
6963 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6964 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6965 hddLog (VOS_TRACE_LEVEL_ERROR,
6966 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6967 return -EIO;
6968 }
6969 }
krunal sonie9002db2013-11-25 14:24:17 -08006970 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6971 {
6972 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6973 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6974 {
6975 hddLog (VOS_TRACE_LEVEL_ERROR,
6976 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6977 return -EIO;
6978 }
6979 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6980 if (!params->bssid)
6981 {
6982 hddLog (VOS_TRACE_LEVEL_ERROR,
6983 "%s:Failed memory allocation", __func__);
6984 return -EIO;
6985 }
6986 vos_mem_copy((v_U8_t *)params->bssid,
6987 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6988 VOS_MAC_ADDR_SIZE);
6989 alloc_bssid = VOS_TRUE;
6990 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006991
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006993 if (NULL !=
6994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6995 params->chandef.chan)
6996#else
6997 params->channel)
6998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 {
7000 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007001 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7002 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7003 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7004 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007005
7006 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307007 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007008 ieee80211_frequency_to_channel(
7009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7010 params->chandef.chan->center_freq);
7011#else
7012 params->channel->center_freq);
7013#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007014
7015 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7016 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7019 __func__);
7020 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007022
7023 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007025 if (channelNum == validChan[indx])
7026 {
7027 break;
7028 }
7029 }
7030 if (indx >= numChans)
7031 {
7032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 __func__, channelNum);
7034 return -EINVAL;
7035 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007036 /* Set the Operational Channel */
7037 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7038 channelNum);
7039 pRoamProfile->ChannelInfo.numOfChannels = 1;
7040 pHddStaCtx->conn_info.operationChannel = channelNum;
7041 pRoamProfile->ChannelInfo.ChannelList =
7042 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 }
7044
7045 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307046 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 if (status < 0)
7048 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307049 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 __func__);
7051 return status;
7052 }
7053
7054 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307055 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007056 params->ssid_len, params->bssid,
7057 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007058
7059 if (0 > status)
7060 {
7061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7062 return status;
7063 }
7064
krunal sonie9002db2013-11-25 14:24:17 -08007065 if (NULL != params->bssid &&
7066 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7067 alloc_bssid == VOS_TRUE)
7068 {
7069 vos_mem_free(params->bssid);
7070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 return 0;
7072}
7073
7074/*
7075 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307078static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 struct net_device *dev
7080 )
7081{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7084 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307085 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7086 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007087
7088 ENTER();
7089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7091 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7092 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307093 status = wlan_hdd_validate_context(pHddCtx);
7094
7095 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007096 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7098 "%s: HDD context is not valid", __func__);
7099 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007100 }
7101
Arif Hussain6d2a3322013-11-17 19:50:10 -08007102 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 if (NULL == pWextState)
7104 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007105 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 __func__);
7107 return -EIO;
7108 }
7109
7110 pRoamProfile = &pWextState->roamProfile;
7111
7112 /* Issue disconnect only if interface type is set to IBSS */
7113 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307115 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 __func__);
7117 return -EINVAL;
7118 }
7119
7120 /* Issue Disconnect request */
7121 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7122 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7123 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7124
7125 return 0;
7126}
7127
7128/*
7129 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7130 * This function is used to set the phy parameters
7131 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7132 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307133static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 u32 changed)
7135{
7136 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7137 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307138 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007139
7140 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7142 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7143 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307144 status = wlan_hdd_validate_context(pHddCtx);
7145
7146 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007147 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7149 "%s: HDD context is not valid", __func__);
7150 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007151 }
7152
Jeff Johnson295189b2012-06-20 16:38:30 -07007153 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7154 {
7155 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7156 WNI_CFG_RTS_THRESHOLD_STAMAX :
7157 wiphy->rts_threshold;
7158
7159 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307160 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307162 hddLog(VOS_TRACE_LEVEL_ERROR,
7163 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 __func__, rts_threshold);
7165 return -EINVAL;
7166 }
7167
7168 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7169 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307170 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307172 hddLog(VOS_TRACE_LEVEL_ERROR,
7173 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007174 __func__, rts_threshold);
7175 return -EIO;
7176 }
7177
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307178 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 rts_threshold);
7180 }
7181
7182 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7183 {
7184 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7185 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7186 wiphy->frag_threshold;
7187
7188 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307189 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007190 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307191 hddLog(VOS_TRACE_LEVEL_ERROR,
7192 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007193 frag_threshold);
7194 return -EINVAL;
7195 }
7196
7197 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7198 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307199 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307201 hddLog(VOS_TRACE_LEVEL_ERROR,
7202 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 __func__, frag_threshold);
7204 return -EIO;
7205 }
7206
7207 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7208 frag_threshold);
7209 }
7210
7211 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7212 || (changed & WIPHY_PARAM_RETRY_LONG))
7213 {
7214 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7215 wiphy->retry_short :
7216 wiphy->retry_long;
7217
7218 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7219 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7220 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 __func__, retry_value);
7223 return -EINVAL;
7224 }
7225
7226 if (changed & WIPHY_PARAM_RETRY_SHORT)
7227 {
7228 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7229 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307230 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 hddLog(VOS_TRACE_LEVEL_ERROR,
7233 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 __func__, retry_value);
7235 return -EIO;
7236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307237 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 __func__, retry_value);
7239 }
7240 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7241 {
7242 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7243 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307244 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307246 hddLog(VOS_TRACE_LEVEL_ERROR,
7247 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 __func__, retry_value);
7249 return -EIO;
7250 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307251 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 __func__, retry_value);
7253 }
7254 }
7255
7256 return 0;
7257}
7258
7259/*
7260 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7261 * This function is used to set the txpower
7262 */
7263static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007264#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7265 struct wireless_dev *wdev,
7266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007267#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307268 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007269#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307270 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007271#endif
7272 int dbm)
7273{
7274 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307275 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007276 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7277 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307278 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007279
7280 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307281 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7282 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7283 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307284 status = wlan_hdd_validate_context(pHddCtx);
7285
7286 if (0 != status)
7287 {
7288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7289 "%s: HDD context is not valid", __func__);
7290 return status;
7291 }
7292
7293 hHal = pHddCtx->hHal;
7294
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7296 dbm, ccmCfgSetCallback,
7297 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307299 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7301 return -EIO;
7302 }
7303
7304 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7305 dbm);
7306
7307 switch(type)
7308 {
7309 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7310 /* Fall through */
7311 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7312 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7315 __func__);
7316 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 }
7318 break;
7319 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 __func__);
7322 return -EOPNOTSUPP;
7323 break;
7324 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7326 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 return -EIO;
7328 }
7329
7330 return 0;
7331}
7332
7333/*
7334 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7335 * This function is used to read the txpower
7336 */
Yue Maf49ba872013-08-19 12:04:25 -07007337static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7338#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7339 struct wireless_dev *wdev,
7340#endif
7341 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007342{
7343
7344 hdd_adapter_t *pAdapter;
7345 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307346 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007347
Jeff Johnsone7245742012-09-05 17:12:55 -07007348 ENTER();
7349
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307350 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007351
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307352 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007353 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7355 "%s: HDD context is not valid", __func__);
7356 *dbm = 0;
7357 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007358 }
7359
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7361 if (NULL == pAdapter)
7362 {
7363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7364 return -ENOENT;
7365 }
7366
7367 wlan_hdd_get_classAstats(pAdapter);
7368 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7369
Jeff Johnsone7245742012-09-05 17:12:55 -07007370 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 return 0;
7372}
7373
7374static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7375 u8* mac, struct station_info *sinfo)
7376{
7377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7378 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7379 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7380 tANI_U8 rate_flags;
7381
7382 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7383 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007384
7385 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7386 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7387 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7388 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7389 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7390 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7391 tANI_U16 maxRate = 0;
7392 tANI_U16 myRate;
7393 tANI_U16 currentRate = 0;
7394 tANI_U8 maxSpeedMCS = 0;
7395 tANI_U8 maxMCSIdx = 0;
7396 tANI_U8 rateFlag = 1;
7397 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007398 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307399 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007400
Leo Chang6f8870f2013-03-26 18:11:36 -07007401#ifdef WLAN_FEATURE_11AC
7402 tANI_U32 vht_mcs_map;
7403 eDataRate11ACMaxMcs vhtMaxMcs;
7404#endif /* WLAN_FEATURE_11AC */
7405
Jeff Johnsone7245742012-09-05 17:12:55 -07007406 ENTER();
7407
Jeff Johnson295189b2012-06-20 16:38:30 -07007408 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7409 (0 == ssidlen))
7410 {
7411 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7412 " Invalid ssidlen, %d", __func__, ssidlen);
7413 /*To keep GUI happy*/
7414 return 0;
7415 }
7416
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307417 status = wlan_hdd_validate_context(pHddCtx);
7418
7419 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007420 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7422 "%s: HDD context is not valid", __func__);
7423 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007424 }
7425
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007426 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7428
Kiet Lam3b17fc82013-09-27 05:24:08 +05307429 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7430 sinfo->filled |= STATION_INFO_SIGNAL;
7431
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 //convert to the UI units of 100kbps
7433 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7434
7435#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007436 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 -07007437 sinfo->signal,
7438 pCfg->reportMaxLinkSpeed,
7439 myRate,
7440 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007441 (int) pCfg->linkSpeedRssiMid,
7442 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007443 (int) rate_flags,
7444 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007445#endif //LINKSPEED_DEBUG_ENABLED
7446
7447 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7448 {
7449 // we do not want to necessarily report the current speed
7450 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7451 {
7452 // report the max possible speed
7453 rssidx = 0;
7454 }
7455 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7456 {
7457 // report the max possible speed with RSSI scaling
7458 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7459 {
7460 // report the max possible speed
7461 rssidx = 0;
7462 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007463 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 {
7465 // report middle speed
7466 rssidx = 1;
7467 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007468 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7469 {
7470 // report middle speed
7471 rssidx = 2;
7472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 else
7474 {
7475 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007476 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 }
7478 }
7479 else
7480 {
7481 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7482 hddLog(VOS_TRACE_LEVEL_ERROR,
7483 "%s: Invalid value for reportMaxLinkSpeed: %u",
7484 __func__, pCfg->reportMaxLinkSpeed);
7485 rssidx = 0;
7486 }
7487
7488 maxRate = 0;
7489
7490 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307491 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7492 OperationalRates, &ORLeng))
7493 {
7494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7495 /*To keep GUI happy*/
7496 return 0;
7497 }
7498
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 for (i = 0; i < ORLeng; i++)
7500 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007501 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 {
7503 /* Validate Rate Set */
7504 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7505 {
7506 currentRate = supported_data_rate[j].supported_rate[rssidx];
7507 break;
7508 }
7509 }
7510 /* Update MAX rate */
7511 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7512 }
7513
7514 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307515 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7516 ExtendedRates, &ERLeng))
7517 {
7518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7519 /*To keep GUI happy*/
7520 return 0;
7521 }
7522
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 for (i = 0; i < ERLeng; i++)
7524 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007525 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 {
7527 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7528 {
7529 currentRate = supported_data_rate[j].supported_rate[rssidx];
7530 break;
7531 }
7532 }
7533 /* Update MAX rate */
7534 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7535 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307536 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307537 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307538 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307539 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307540 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307542 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7543 MCSRates, &MCSLeng))
7544 {
7545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7546 /*To keep GUI happy*/
7547 return 0;
7548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007550#ifdef WLAN_FEATURE_11AC
7551 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307552 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007554 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307555 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007556 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007558 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007560 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007562 maxMCSIdx = 7;
7563 }
7564 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7565 {
7566 maxMCSIdx = 8;
7567 }
7568 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7569 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307570 //VHT20 is supporting 0~8
7571 if (rate_flags & eHAL_TX_RATE_VHT20)
7572 maxMCSIdx = 8;
7573 else
7574 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007575 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307576
7577 if (rate_flags & eHAL_TX_RATE_VHT80)
7578 {
7579 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7580 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7581 }
7582 else if (rate_flags & eHAL_TX_RATE_VHT40)
7583 {
7584 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7585 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7586 }
7587 else if (rate_flags & eHAL_TX_RATE_VHT20)
7588 {
7589 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7590 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7591 }
7592
Leo Chang6f8870f2013-03-26 18:11:36 -07007593 maxSpeedMCS = 1;
7594 if (currentRate > maxRate)
7595 {
7596 maxRate = currentRate;
7597 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307598
Leo Chang6f8870f2013-03-26 18:11:36 -07007599 }
7600 else
7601#endif /* WLAN_FEATURE_11AC */
7602 {
7603 if (rate_flags & eHAL_TX_RATE_HT40)
7604 {
7605 rateFlag |= 1;
7606 }
7607 if (rate_flags & eHAL_TX_RATE_SGI)
7608 {
7609 rateFlag |= 2;
7610 }
7611
7612 for (i = 0; i < MCSLeng; i++)
7613 {
7614 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7615 for (j = 0; j < temp; j++)
7616 {
7617 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7618 {
7619 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7620 break;
7621 }
7622 }
7623 if ((j < temp) && (currentRate > maxRate))
7624 {
7625 maxRate = currentRate;
7626 maxSpeedMCS = 1;
7627 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 }
7630 }
7631 }
7632
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307633 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7634 {
7635 maxRate = myRate;
7636 maxSpeedMCS = 1;
7637 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7638 }
7639
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007641 if (((maxRate < myRate) && (0 == rssidx)) ||
7642 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 {
7644 maxRate = myRate;
7645 if (rate_flags & eHAL_TX_RATE_LEGACY)
7646 {
7647 maxSpeedMCS = 0;
7648 }
7649 else
7650 {
7651 maxSpeedMCS = 1;
7652 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7653 }
7654 }
7655
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307656 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 {
7658 sinfo->txrate.legacy = maxRate;
7659#ifdef LINKSPEED_DEBUG_ENABLED
7660 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7661#endif //LINKSPEED_DEBUG_ENABLED
7662 }
7663 else
7664 {
7665 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007666#ifdef WLAN_FEATURE_11AC
7667 sinfo->txrate.nss = 1;
7668 if (rate_flags & eHAL_TX_RATE_VHT80)
7669 {
7670 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307671 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007672 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307673 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007674 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307675 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7676 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7677 }
7678 else if (rate_flags & eHAL_TX_RATE_VHT20)
7679 {
7680 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7681 }
7682#endif /* WLAN_FEATURE_11AC */
7683 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7684 {
7685 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7686 if (rate_flags & eHAL_TX_RATE_HT40)
7687 {
7688 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7689 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 if (rate_flags & eHAL_TX_RATE_SGI)
7692 {
7693 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7694 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307695
Jeff Johnson295189b2012-06-20 16:38:30 -07007696#ifdef LINKSPEED_DEBUG_ENABLED
7697 pr_info("Reporting MCS rate %d flags %x\n",
7698 sinfo->txrate.mcs,
7699 sinfo->txrate.flags );
7700#endif //LINKSPEED_DEBUG_ENABLED
7701 }
7702 }
7703 else
7704 {
7705 // report current rate instead of max rate
7706
7707 if (rate_flags & eHAL_TX_RATE_LEGACY)
7708 {
7709 //provide to the UI in units of 100kbps
7710 sinfo->txrate.legacy = myRate;
7711#ifdef LINKSPEED_DEBUG_ENABLED
7712 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7713#endif //LINKSPEED_DEBUG_ENABLED
7714 }
7715 else
7716 {
7717 //must be MCS
7718 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007719#ifdef WLAN_FEATURE_11AC
7720 sinfo->txrate.nss = 1;
7721 if (rate_flags & eHAL_TX_RATE_VHT80)
7722 {
7723 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7724 }
7725 else
7726#endif /* WLAN_FEATURE_11AC */
7727 {
7728 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007730 if (rate_flags & eHAL_TX_RATE_SGI)
7731 {
7732 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7733 }
7734 if (rate_flags & eHAL_TX_RATE_HT40)
7735 {
7736 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7737 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007738#ifdef WLAN_FEATURE_11AC
7739 else if (rate_flags & eHAL_TX_RATE_VHT80)
7740 {
7741 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7742 }
7743#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007744#ifdef LINKSPEED_DEBUG_ENABLED
7745 pr_info("Reporting actual MCS rate %d flags %x\n",
7746 sinfo->txrate.mcs,
7747 sinfo->txrate.flags );
7748#endif //LINKSPEED_DEBUG_ENABLED
7749 }
7750 }
7751 sinfo->filled |= STATION_INFO_TX_BITRATE;
7752
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007753 sinfo->tx_packets =
7754 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7755 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7756 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7757 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7758
7759 sinfo->tx_retries =
7760 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7761 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7762 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7763 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7764
7765 sinfo->tx_failed =
7766 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7767 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7768 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7769 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7770
7771 sinfo->filled |=
7772 STATION_INFO_TX_PACKETS |
7773 STATION_INFO_TX_RETRIES |
7774 STATION_INFO_TX_FAILED;
7775
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307776 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7777 TRACE_CODE_HDD_CFG80211_GET_STA,
7778 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007779 EXIT();
7780 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007781}
7782
7783static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007784 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007785{
7786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307787 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307789 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007790
Jeff Johnsone7245742012-09-05 17:12:55 -07007791 ENTER();
7792
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 if (NULL == pAdapter)
7794 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 return -ENODEV;
7797 }
7798
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7800 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7801 pAdapter->sessionId, timeout));
7802
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307803 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307804 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307805
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307806 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7809 "%s: HDD context is not valid", __func__);
7810 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307811 }
7812
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307813 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7814 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7815 (pHddCtx->cfg_ini->fhostArpOffload) &&
7816 (eConnectionState_Associated ==
7817 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7818 {
Amar Singhald53568e2013-09-26 11:03:45 -07007819
7820 hddLog(VOS_TRACE_LEVEL_INFO,
7821 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307822 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307823 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7824 {
7825 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007826 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307827 __func__, vos_status);
7828 }
7829 }
7830
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 /**The get power cmd from the supplicant gets updated by the nl only
7832 *on successful execution of the function call
7833 *we are oppositely mapped w.r.t mode in the driver
7834 **/
7835 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7836
Jeff Johnsone7245742012-09-05 17:12:55 -07007837 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 if (VOS_STATUS_E_FAILURE == vos_status)
7839 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7841 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 return -EINVAL;
7843 }
7844 return 0;
7845}
7846
7847
7848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7849static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7850 struct net_device *netdev,
7851 u8 key_index)
7852{
Jeff Johnsone7245742012-09-05 17:12:55 -07007853 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 return 0;
7855}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307856#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007857
7858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7859static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7860 struct net_device *dev,
7861 struct ieee80211_txq_params *params)
7862{
Jeff Johnsone7245742012-09-05 17:12:55 -07007863 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 return 0;
7865}
7866#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7867static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7868 struct ieee80211_txq_params *params)
7869{
Jeff Johnsone7245742012-09-05 17:12:55 -07007870 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return 0;
7872}
7873#endif //LINUX_VERSION_CODE
7874
7875static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7876 struct net_device *dev, u8 *mac)
7877{
7878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307879 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007880 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307881 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007882 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007883
Jeff Johnsone7245742012-09-05 17:12:55 -07007884 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307885
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307886 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 return -EINVAL;
7890 }
7891
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307892 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7893 TRACE_CODE_HDD_CFG80211_DEL_STA,
7894 pAdapter->sessionId, pAdapter->device_mode));
7895
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307896 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7897 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007898
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307899 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7902 "%s: HDD context is not valid", __func__);
7903 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007904 }
7905
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 )
7909 {
7910 if( NULL == mac )
7911 {
7912 v_U16_t i;
7913 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7914 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007915 if ((pAdapter->aStaInfo[i].isUsed) &&
7916 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 {
7918 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7919 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007920 "%s: Delete STA with MAC::"
7921 MAC_ADDRESS_STR,
7922 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007923 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7924 if (VOS_IS_STATUS_SUCCESS(vos_status))
7925 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 }
7927 }
7928 }
7929 else
7930 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007931
7932 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7933 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7934 {
7935 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007936 "%s: Skip this DEL STA as this is not used::"
7937 MAC_ADDRESS_STR,
7938 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007939 return -ENOENT;
7940 }
7941
7942 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7943 {
7944 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007945 "%s: Skip this DEL STA as deauth is in progress::"
7946 MAC_ADDRESS_STR,
7947 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007948 return -ENOENT;
7949 }
7950
7951 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7952
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 hddLog(VOS_TRACE_LEVEL_INFO,
7954 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007955 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007956 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007957 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007958
7959 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7960 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7961 {
7962 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7963 hddLog(VOS_TRACE_LEVEL_INFO,
7964 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007965 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007966 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007967 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007968 return -ENOENT;
7969 }
7970
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 }
7972 }
7973
7974 EXIT();
7975
7976 return 0;
7977}
7978
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007979static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7980 struct net_device *dev, u8 *mac, struct station_parameters *params)
7981{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007983 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007984#ifdef FEATURE_WLAN_TDLS
7985 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007986 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307987
7988 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7989 TRACE_CODE_HDD_CFG80211_ADD_STA,
7990 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007991 mask = params->sta_flags_mask;
7992
7993 set = params->sta_flags_set;
7994
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007995#ifdef WLAN_FEATURE_TDLS_DEBUG
7996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7997 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7998 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7999#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008000
8001 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8002 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008003 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008004 }
8005 }
8006#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008007 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008008}
8009
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008010
8011#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008012#define MAX_PMKSAIDS_IN_CACHE 8
8013
8014static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8015static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8016
8017
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008018static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008019 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008020{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308021 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8023 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308024 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308025 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008026 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308027 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008028 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8029 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008030
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308031 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308032 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008035 return -EINVAL;
8036 }
8037
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8039 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008040
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308041 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8044 "%s: HDD context is not valid", __func__);
8045 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008046 }
8047
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308048 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008049 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8050
Wilson Yang6507c4e2013-10-01 20:11:19 -07008051 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008052 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308053 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008054 pmksa->bssid, WNI_CFG_BSSID_LEN))
8055 {
8056 /* BSSID matched previous entry. Overwrite it. */
8057 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308058 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008059 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308060 vos_mem_copy(PMKIDCache[j].PMKID,
8061 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008062 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308063 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008064 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008065 dump_bssid(pmksa->bssid);
8066 dump_pmkid(halHandle, pmksa->pmkid);
8067 break;
8068 }
8069 }
8070
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008071 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008072 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008073
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008074 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308075 {
8076 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008077 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308078 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008079 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008081 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308082 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008083 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008084 dump_bssid(pmksa->bssid);
8085 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308086 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008087 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008088 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008089 }
8090
8091
8092 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308093 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008094 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308095 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008096 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008097 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308098 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8099 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008100 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308101 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8102 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8103 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008104 return 0;
8105}
8106
8107
Wilson Yang6507c4e2013-10-01 20:11:19 -07008108
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008109static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008110 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008111{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008112 tANI_U32 j=0;
8113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8114 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008115 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008116 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008117 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008118
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008119 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8120 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008121
8122 /* Validate pAdapter */
8123 if (NULL == pAdapter)
8124 {
8125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8126 return -EINVAL;
8127 }
8128
8129 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8130 status = wlan_hdd_validate_context(pHddCtx);
8131
8132 if (0 != status)
8133 {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s: HDD context is not valid", __func__);
8136 return status;
8137 }
8138
8139 /*Retrieve halHandle*/
8140 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8141
8142 /*in case index is 0,no entry to delete*/
8143 if (0 == PMKIDCacheIndex)
8144 {
8145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8146 __func__);
8147 return -EINVAL;
8148 }
8149
8150 /*find the matching PMKSA entry from j=0 to (index-1),
8151 * and delete the matched one
8152 */
8153 for (j = 0; j<PMKIDCacheIndex; j++)
8154 {
8155 if (vos_mem_compare(PMKIDCache[j].BSSID,
8156 pmksa->bssid,
8157 WNI_CFG_BSSID_LEN))
8158 {
8159 /* BSSID matched entry */
8160 BSSIDMatched = 1;
8161
8162 if (j<PMKIDCacheIndex-1)
8163 {
8164 /*replace the matching entry with the last entry in HDD local cache*/
8165 vos_mem_copy(PMKIDCache[j].BSSID,
8166 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8167 WNI_CFG_BSSID_LEN);
8168 vos_mem_copy(PMKIDCache[j].PMKID,
8169 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8170 CSR_RSN_PMKID_SIZE);
8171 }
8172
8173 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008174 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8175 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8176
8177 /*reduce the PMKID array index*/
8178 PMKIDCacheIndex--;
8179
8180 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008181 if (eHAL_STATUS_SUCCESS !=
8182 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008183 {
8184 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8185 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008186 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008187 }
8188
8189 dump_bssid(pmksa->bssid);
8190 dump_pmkid(halHandle,pmksa->pmkid);
8191
8192 break;
8193 }
8194 }
8195
8196 /* we compare all entries,but cannot find matching entry */
8197 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8198 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008199 hddLog(VOS_TRACE_LEVEL_FATAL,
8200 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8201 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008202 dump_bssid(pmksa->bssid);
8203 dump_pmkid(halHandle, pmksa->pmkid);
8204 return -EINVAL;
8205 }
Wilson Yangef657d32014-01-15 19:19:23 -08008206 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008207}
8208
Wilson Yang6507c4e2013-10-01 20:11:19 -07008209
8210
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008211static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8212{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008213 tANI_U32 j=0;
8214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8215 tHalHandle halHandle;
8216 hdd_context_t *pHddCtx;
8217 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008218 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008219
8220 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8221
8222 /* Validate pAdapter */
8223 if (NULL == pAdapter)
8224 {
8225 hddLog(VOS_TRACE_LEVEL_ERROR,
8226 "%s: Invalid Adapter" ,__func__);
8227 return -EINVAL;
8228 }
8229
8230 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8231 status = wlan_hdd_validate_context(pHddCtx);
8232
8233 if (0 != status)
8234 {
8235 hddLog(VOS_TRACE_LEVEL_ERROR,
8236 "%s: HDD context is not valid", __func__);
8237 return status;
8238 }
8239
8240 /*Retrieve halHandle*/
8241 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8242
8243 /*in case index is 0,no entry to delete*/
8244 if (0 == PMKIDCacheIndex)
8245 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008247 return -EINVAL;
8248 }
8249
8250 /*delete all the PMKSA one by one */
8251 for (j = 0; j<PMKIDCacheIndex; j++)
8252 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008253 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008254
8255 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008256 if (eHAL_STATUS_SUCCESS !=
8257 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008258 {
8259 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8260 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008261 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008262 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308263 /*clear the entry in HDD cache 0--index-1 */
8264 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8265 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008266 }
8267
8268 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008269 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008270}
8271#endif
8272
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008273#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308274static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008275 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8276{
8277 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8278 hdd_station_ctx_t *pHddStaCtx;
8279
8280 if (NULL == pAdapter)
8281 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008283 return -ENODEV;
8284 }
8285
8286 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8287
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8289 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8290 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008291 // Added for debug on reception of Re-assoc Req.
8292 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8293 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008294 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008295 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008296 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008297 }
8298
8299#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008300 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008301 ftie->ie_len);
8302#endif
8303
8304 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308305 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8306 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008307 ftie->ie_len);
8308 return 0;
8309}
8310#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308312#ifdef FEATURE_WLAN_SCAN_PNO
8313
8314void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8315 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8316{
8317 int ret;
8318 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8319 hdd_context_t *pHddCtx;
8320
Nirav Shah80830bf2013-12-31 16:35:12 +05308321 ENTER();
8322
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308323 if (NULL == pAdapter)
8324 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308326 "%s: HDD adapter is Null", __func__);
8327 return ;
8328 }
8329
8330 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8331 if (NULL == pHddCtx)
8332 {
8333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8334 "%s: HDD context is Null!!!", __func__);
8335 return ;
8336 }
8337
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308338 spin_lock(&pHddCtx->schedScan_lock);
8339 if (TRUE == pHddCtx->isWiphySuspended)
8340 {
8341 pHddCtx->isSchedScanUpdatePending = TRUE;
8342 spin_unlock(&pHddCtx->schedScan_lock);
8343 hddLog(VOS_TRACE_LEVEL_INFO,
8344 "%s: Update cfg80211 scan database after it resume", __func__);
8345 return ;
8346 }
8347 spin_unlock(&pHddCtx->schedScan_lock);
8348
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308349 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8350
8351 if (0 > ret)
8352 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8353
8354 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8356 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308357}
8358
8359/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308360 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308361 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308362 */
8363static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8364{
8365 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8366 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308367 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308368 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8369 int status = 0;
8370 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8371
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308372 /* The current firmware design does not allow PNO during any
8373 * active sessions. Hence, determine the active sessions
8374 * and return a failure.
8375 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308376 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8377 {
8378 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308379 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308380
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308381 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8382 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8383 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8384 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8385 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8386 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308387 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308388 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308389 }
8390 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8391 pAdapterNode = pNext;
8392 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308393 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308394}
8395
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308396void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8397{
8398 hdd_adapter_t *pAdapter = callbackContext;
8399 hdd_context_t *pHddCtx;
8400
8401 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8402 {
8403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8404 FL("Invalid adapter or adapter has invalid magic"));
8405 return;
8406 }
8407
8408 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8409 if (0 != wlan_hdd_validate_context(pHddCtx))
8410 {
8411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8412 FL("HDD context is not valid"));
8413 return;
8414 }
8415
8416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8417 FL("PNO enable response status = %d"), status);
8418
8419 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8420 complete(&pAdapter->pno_comp_var);
8421}
8422
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308423/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308424 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8425 * NL interface to enable PNO
8426 */
8427static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8428 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8429{
8430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8431 tpSirPNOScanReq pPnoRequest = NULL;
8432 hdd_context_t *pHddCtx;
8433 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308434 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308435 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8436 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308437 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8438 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308439 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308440
8441 if (NULL == pAdapter)
8442 {
8443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8444 "%s: HDD adapter is Null", __func__);
8445 return -ENODEV;
8446 }
8447
8448 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308449 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308450
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308451 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308452 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8454 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308455 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308456 }
8457
8458 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8459 if (NULL == hHal)
8460 {
8461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8462 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308463 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308464 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308465
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308466 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308467 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308469 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308470 return -EBUSY;
8471 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308472
c_hpothu37f21312014-04-09 21:49:54 +05308473 if (TRUE == pHddCtx->isPnoEnable)
8474 {
8475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8476 FL("already PNO is enabled"));
8477 return -EBUSY;
8478 }
8479 pHddCtx->isPnoEnable = TRUE;
8480
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308481 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8482 if (NULL == pPnoRequest)
8483 {
8484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8485 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308486 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308487 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308488 }
8489
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308490 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308491 pPnoRequest->enable = 1; /*Enable PNO */
8492 pPnoRequest->ucNetworksCount = request->n_match_sets;
8493
8494 if (( !pPnoRequest->ucNetworksCount ) ||
8495 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8496 {
8497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308498 "%s: Network input is not correct %d",
8499 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308500 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308501 goto error;
8502 }
8503
8504 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8505 {
8506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308507 "%s: Incorrect number of channels %d",
8508 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308509 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308510 goto error;
8511 }
8512
8513 /* Framework provides one set of channels(all)
8514 * common for all saved profile */
8515 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8516 channels_allowed, &num_channels_allowed))
8517 {
8518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8519 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308520 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308521 goto error;
8522 }
8523 /* Checking each channel against allowed channel list */
8524 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308525 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308526 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308527 char chList [(request->n_channels*5)+1];
8528 int len;
8529 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308530 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308531 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308532 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308533 if (request->channels[i]->hw_value == channels_allowed[indx])
8534 {
8535 valid_ch[num_ch++] = request->channels[i]->hw_value;
8536 len += snprintf(chList+len, 5, "%d ",
8537 request->channels[i]->hw_value);
8538 break ;
8539 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308540 }
8541 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308542 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8543 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308544
8545 /* Filling per profile params */
8546 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8547 {
8548 pPnoRequest->aNetworks[i].ssId.length =
8549 request->match_sets[i].ssid.ssid_len;
8550
8551 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8552 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8553 {
8554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308555 "%s: SSID Len %d is not correct for network %d",
8556 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308557 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308558 goto error;
8559 }
8560
8561 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8562 request->match_sets[i].ssid.ssid,
8563 request->match_sets[i].ssid.ssid_len);
8564 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8565 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8566 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8567
8568 /*Copying list of valid channel into request */
8569 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8570 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8571
8572 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8573 }
8574
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008576 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308577 if ((0 < request->ie_len) && (NULL != request->ie))
8578 {
8579 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8580 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8581 pPnoRequest->us24GProbeTemplateLen);
8582
8583 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8584 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8585 pPnoRequest->us5GProbeTemplateLen);
8586 }
8587
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308588 /* Driver gets only one time interval which is hardcoded in
8589 * supplicant for 10000ms. Taking power consumption into account 6 timers
8590 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8591 * 80,160,320 secs. And number of scan cycle for each timer
8592 * is configurable through INI param gPNOScanTimerRepeatValue.
8593 * If it is set to 0 only one timer will be used and PNO scan cycle
8594 * will be repeated after each interval specified by supplicant
8595 * till PNO is disabled.
8596 */
8597 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8598 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8599 else
8600 pPnoRequest->scanTimers.ucScanTimersCount =
8601 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8602
8603 tempInterval = (request->interval)/1000;
8604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8605 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8606 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8607 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8608 {
8609 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8610 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8611 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8612 tempInterval *= 2;
8613 }
8614 //Repeat last timer until pno disabled.
8615 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8616
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308617 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308618
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308619 INIT_COMPLETION(pAdapter->pno_comp_var);
8620 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8621 pPnoRequest->callbackContext = pAdapter;
8622 pAdapter->pno_req_status = 0;
8623
Nirav Shah80830bf2013-12-31 16:35:12 +05308624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8625 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8626 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8627 pPnoRequest->scanTimers.ucScanTimersCount);
8628
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308629 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8630 pPnoRequest, pAdapter->sessionId,
8631 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8632 if (eHAL_STATUS_SUCCESS != status)
8633 {
8634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308635 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308636 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308637 goto error;
8638 }
8639
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308640 ret = wait_for_completion_timeout(
8641 &pAdapter->pno_comp_var,
8642 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8643 if (0 >= ret)
8644 {
8645 // Did not receive the response for PNO enable in time.
8646 // Assuming the PNO enable was success.
8647 // Returning error from here, because we timeout, results
8648 // in side effect of Wifi (Wifi Setting) not to work.
8649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8650 FL("Timed out waiting for PNO to be Enabled"));
8651 ret = 0;
8652 goto error;
8653 }
8654
8655 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308656 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308657
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308658error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8660 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308661 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308662 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308663 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308664}
8665
8666/*
8667 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8668 * NL interface to disable PNO
8669 */
8670static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8671 struct net_device *dev)
8672{
8673 eHalStatus status = eHAL_STATUS_FAILURE;
8674 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8675 hdd_context_t *pHddCtx;
8676 tHalHandle hHal;
8677 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308678 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308679
8680 ENTER();
8681
8682 if (NULL == pAdapter)
8683 {
8684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8685 "%s: HDD adapter is Null", __func__);
8686 return -ENODEV;
8687 }
8688
8689 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308690
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308691 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308692 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308694 "%s: HDD context is Null", __func__);
8695 return -ENODEV;
8696 }
8697
8698 /* The return 0 is intentional when isLogpInProgress and
8699 * isLoadUnloadInProgress. We did observe a crash due to a return of
8700 * failure in sched_scan_stop , especially for a case where the unload
8701 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8702 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8703 * success. If it returns a failure , then its next invocation due to the
8704 * clean up of the second interface will have the dev pointer corresponding
8705 * to the first one leading to a crash.
8706 */
8707 if (pHddCtx->isLogpInProgress)
8708 {
8709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8710 "%s: LOGP in Progress. Ignore!!!", __func__);
8711 return ret;
8712 }
8713
Mihir Shete18156292014-03-11 15:38:30 +05308714 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308715 {
8716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8717 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8718 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308719 }
8720
8721 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8722 if (NULL == hHal)
8723 {
8724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8725 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308726 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308727 }
8728
8729 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8730 if (NULL == pPnoRequest)
8731 {
8732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8733 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308734 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308735 }
8736
8737 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8738 pPnoRequest->enable = 0; /* Disable PNO */
8739 pPnoRequest->ucNetworksCount = 0;
8740
8741 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8742 pAdapter->sessionId,
8743 NULL, pAdapter);
8744 if (eHAL_STATUS_SUCCESS != status)
8745 {
8746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8747 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308748 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308749 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308750 }
c_hpothu37f21312014-04-09 21:49:54 +05308751 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308752
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308753error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308755 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308756 vos_mem_free(pPnoRequest);
8757
8758 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308759 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308760}
8761
8762#endif /*FEATURE_WLAN_SCAN_PNO*/
8763
8764
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008765#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308766#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008767static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8768 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308769 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8770#else
8771static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8772 u8 *peer, u8 action_code, u8 dialog_token,
8773 u16 status_code, const u8 *buf, size_t len)
8774#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008775{
8776
8777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8778 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008779 u8 peerMac[6];
8780 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008781 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008782 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008783 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308784#if !(TDLS_MGMT_VERSION2)
8785 u32 peer_capability = 0;
8786#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308787 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008788
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308789 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8790 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8791 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008792 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008793 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008795 "Invalid arguments");
8796 return -EINVAL;
8797 }
8798
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008799 if (pHddCtx->isLogpInProgress)
8800 {
8801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8802 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008803 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008804 return -EBUSY;
8805 }
8806
Hoonki Lee27511902013-03-14 18:19:06 -07008807 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008808 {
Hoonki Lee27511902013-03-14 18:19:06 -07008809 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8810 "%s: TDLS mode is disabled OR not enabled in FW."
8811 MAC_ADDRESS_STR " action %d declined.",
8812 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008813 return -ENOTSUPP;
8814 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008815
Hoonki Lee27511902013-03-14 18:19:06 -07008816 /* other than teardown frame, other mgmt frames are not sent if disabled */
8817 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8818 {
8819 /* if tdls_mode is disabled to respond to peer's request */
8820 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8821 {
8822 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8823 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008824 " TDLS mode is disabled. action %d declined.",
8825 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008826
8827 return -ENOTSUPP;
8828 }
8829 }
8830
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008831 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8832 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308833 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008834 {
8835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008836 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008837 " TDLS setup is ongoing. action %d declined.",
8838 __func__, MAC_ADDR_ARRAY(peer), action_code);
8839 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008840 }
8841 }
8842
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008843 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8844 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008845 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308846 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8847 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008848 {
8849 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8850 we return error code at 'add_station()'. Hence we have this
8851 check again in addtion to add_station().
8852 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008853 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008854 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8856 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308857 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8858 __func__, MAC_ADDR_ARRAY(peer), action_code,
8859 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308860 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008861 }
8862 else
8863 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008864 /* maximum reached. tweak to send error code to peer and return
8865 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008866 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8868 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308869 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8870 __func__, MAC_ADDR_ARRAY(peer), status_code,
8871 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008872 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008873 /* fall through to send setup resp with failure status
8874 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008875 }
8876 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008877 else
8878 {
8879 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308880 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008881 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008882 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008884 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8885 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008886 return -EPERM;
8887 }
8888 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008889 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008890 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008891
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008892#ifdef WLAN_FEATURE_TDLS_DEBUG
8893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308894 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008895 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8896 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008897#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008898
Hoonki Leea34dd892013-02-05 22:56:02 -08008899 /*Except teardown responder will not be used so just make 0*/
8900 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008901 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008902 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008903
8904 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308905 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008906
8907 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8908 responder = pTdlsPeer->is_responder;
8909 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008910 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308912 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008913 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8914 dialog_token, status_code, len);
8915 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008916 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008917 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008918
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308919 /* For explicit trigger of DIS_REQ come out of BMPS for
8920 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008921 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308922 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8923 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008924 {
8925 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8926 {
8927 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308928 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008929 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8930 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308931 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8932 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008933 }
8934
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008935 /* make sure doesn't call send_mgmt() while it is pending */
8936 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8937 {
8938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008939 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008940 __func__, MAC_ADDR_ARRAY(peer), action_code);
8941 return -EBUSY;
8942 }
8943
8944 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008945 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8946
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008947 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05308948 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008949
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008950 if (VOS_STATUS_SUCCESS != status)
8951 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8953 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008954 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008955 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308956 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008957 }
8958
Hoonki Leed37cbb32013-04-20 00:31:14 -07008959 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8960 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8961
8962 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008963 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008965 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008966 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008967 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008968
8969 if (pHddCtx->isLogpInProgress)
8970 {
8971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8972 "%s: LOGP in Progress. Ignore!!!", __func__);
8973 return -EAGAIN;
8974 }
8975
Hoonki Leed37cbb32013-04-20 00:31:14 -07008976 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308977 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008978 }
8979
Gopichand Nakkala05922802013-03-14 12:23:19 -07008980 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008981 {
8982 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008983 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008984 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008985
Hoonki Leea34dd892013-02-05 22:56:02 -08008986 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8987 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008988 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008989 }
8990 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8991 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008992 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008993 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008994
8995 return 0;
8996}
8997
8998static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8999 u8 *peer, enum nl80211_tdls_operation oper)
9000{
9001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9002 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309003 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009004 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009005
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309006 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9007 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9008 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309009 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009010 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009012 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009013 return -EINVAL;
9014 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009015
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309016 status = wlan_hdd_validate_context(pHddCtx);
9017
9018 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009019 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9021 "%s: HDD context is not valid", __func__);
9022 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009023 }
9024
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009025
9026 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009027 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009028 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009030 "TDLS Disabled in INI OR not enabled in FW. "
9031 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009032 return -ENOTSUPP;
9033 }
9034
9035 switch (oper) {
9036 case NL80211_TDLS_ENABLE_LINK:
9037 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009038 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309039 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309040 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009041
Sunil Dutt41de4e22013-11-14 18:09:02 +05309042 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9043
9044 if ( NULL == pTdlsPeer ) {
9045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9046 " (oper %d) not exsting. ignored",
9047 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9048 return -EINVAL;
9049 }
9050
9051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9052 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9053 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9054 "NL80211_TDLS_ENABLE_LINK");
9055
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009056 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9057 {
9058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9059 MAC_ADDRESS_STR " failed",
9060 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9061 return -EINVAL;
9062 }
9063
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009064 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009065 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309066 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309067
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309068 if (0 != wlan_hdd_tdls_get_link_establish_params(
9069 pAdapter, peer,&tdlsLinkEstablishParams)) {
9070 return -EINVAL;
9071 }
9072 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309073
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309074 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9075 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9076 /* Send TDLS peer UAPSD capabilities to the firmware and
9077 * register with the TL on after the response for this operation
9078 * is received .
9079 */
9080 ret = wait_for_completion_interruptible_timeout(
9081 &pAdapter->tdls_link_establish_req_comp,
9082 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9083 if (ret <= 0)
9084 {
9085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9086 "%s: Link Establish Request Faled Status %ld",
9087 __func__, ret);
9088 return -EINVAL;
9089 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309090 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009091 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309092 /* Mark TDLS client Authenticated .*/
9093 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9094 pTdlsPeer->staId,
9095 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009096 if (VOS_STATUS_SUCCESS == status)
9097 {
Hoonki Lee14621352013-04-16 17:51:19 -07009098 if (pTdlsPeer->is_responder == 0)
9099 {
9100 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9101
9102 wlan_hdd_tdls_timer_restart(pAdapter,
9103 &pTdlsPeer->initiatorWaitTimeoutTimer,
9104 WAIT_TIME_TDLS_INITIATOR);
9105 /* suspend initiator TX until it receives direct packet from the
9106 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9107 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9108 &staId, NULL);
9109 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009110 wlan_hdd_tdls_increment_peer_count(pAdapter);
9111 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009112 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309113
9114 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309115 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9116 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309117 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309118 int ac;
9119 uint8 ucAc[4] = { WLANTL_AC_VO,
9120 WLANTL_AC_VI,
9121 WLANTL_AC_BK,
9122 WLANTL_AC_BE };
9123 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9124 for(ac=0; ac < 4; ac++)
9125 {
9126 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9127 pTdlsPeer->staId, ucAc[ac],
9128 tlTid[ac], tlTid[ac], 0, 0,
9129 WLANTL_BI_DIR );
9130 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309131 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009132 }
9133
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009134 }
9135 break;
9136 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009137 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309138 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9139
9140 if ( NULL == pTdlsPeer ) {
9141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9142 " (oper %d) not exsting. ignored",
9143 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9144 return -EINVAL;
9145 }
9146
9147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9148 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9149 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9150 "NL80211_TDLS_DISABLE_LINK");
9151
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009152 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009153 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009154 long status;
9155
9156 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9157
Lee Hoonkic1262f22013-01-24 21:59:00 -08009158 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9159 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009160
9161 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9162 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9163 if (status <= 0)
9164 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009165 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9167 "%s: Del station failed status %ld",
9168 __func__, status);
9169 return -EPERM;
9170 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009171 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009172 }
9173 else
9174 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9176 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009177 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009178 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009179 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009180 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309181 {
9182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9183 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9184 __func__, MAC_ADDR_ARRAY(peer));
9185
9186 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9187 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9188
9189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9190 " %s TDLS External control and Implicit Trigger not enabled ",
9191 __func__);
9192 return -ENOTSUPP;
9193 }
9194
Sunil Dutt41de4e22013-11-14 18:09:02 +05309195
9196 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9197
9198 if ( NULL == pTdlsPeer ) {
9199 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9200 " peer not exsting",
9201 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309202 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309203 }
9204 else {
9205 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9206 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9207 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309208
9209 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9210 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309211 break;
9212 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009213 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309214 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309215 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9217 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9218 __func__, MAC_ADDR_ARRAY(peer));
9219
9220 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9221 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9222
9223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9224 " %s TDLS External control and Implicit Trigger not enabled ",
9225 __func__);
9226 return -ENOTSUPP;
9227 }
9228
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309229 /* To cater the requirement of establishing the TDLS link
9230 * irrespective of the data traffic , get an entry of TDLS peer.
9231 */
9232 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9233 if (pTdlsPeer == NULL) {
9234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9235 "%s: peer " MAC_ADDRESS_STR " not existing",
9236 __func__, MAC_ADDR_ARRAY(peer));
9237 return -EINVAL;
9238 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309239
9240 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9241
9242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9243 " %s TDLS Add Force Peer Failed",
9244 __func__);
9245 return -EINVAL;
9246 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309247 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309248 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009249 case NL80211_TDLS_DISCOVERY_REQ:
9250 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9252 "%s: We don't support in-driver setup/teardown/discovery "
9253 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009254 return -ENOTSUPP;
9255 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9257 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009258 return -ENOTSUPP;
9259 }
9260 return 0;
9261}
Chilam NG571c65a2013-01-19 12:27:36 +05309262
9263int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9264 struct net_device *dev, u8 *peer)
9265{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009266 hddLog(VOS_TRACE_LEVEL_INFO,
9267 "tdls send discover req: "MAC_ADDRESS_STR,
9268 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309269
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309270#if TDLS_MGMT_VERSION2
9271 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9272 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9273#else
Chilam NG571c65a2013-01-19 12:27:36 +05309274 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9275 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309276#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309277}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009278#endif
9279
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309280#ifdef WLAN_FEATURE_GTK_OFFLOAD
9281/*
9282 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9283 * Callback rountine called upon receiving response for
9284 * get offload info
9285 */
9286void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9287 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9288{
9289
9290 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309291 tANI_U8 tempReplayCounter[8];
9292 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309293
9294 ENTER();
9295
9296 if (NULL == pAdapter)
9297 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309299 "%s: HDD adapter is Null", __func__);
9300 return ;
9301 }
9302
9303 if (NULL == pGtkOffloadGetInfoRsp)
9304 {
9305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9306 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9307 return ;
9308 }
9309
9310 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9311 {
9312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9313 "%s: wlan Failed to get replay counter value",
9314 __func__);
9315 return ;
9316 }
9317
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309318 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9319 /* Update replay counter */
9320 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9321 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9322
9323 {
9324 /* changing from little to big endian since supplicant
9325 * works on big endian format
9326 */
9327 int i;
9328 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9329
9330 for (i = 0; i < 8; i++)
9331 {
9332 tempReplayCounter[7-i] = (tANI_U8)p[i];
9333 }
9334 }
9335
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309336 /* Update replay counter to NL */
9337 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309338 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309339}
9340
9341/*
9342 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9343 * This function is used to offload GTK rekeying job to the firmware.
9344 */
9345int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9346 struct cfg80211_gtk_rekey_data *data)
9347{
9348 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9349 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9350 hdd_station_ctx_t *pHddStaCtx;
9351 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309352 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309353 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309354 eHalStatus status = eHAL_STATUS_FAILURE;
9355
9356 ENTER();
9357
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309358
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309359 if (NULL == pAdapter)
9360 {
9361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9362 "%s: HDD adapter is Null", __func__);
9363 return -ENODEV;
9364 }
9365
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9367 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9368 pAdapter->sessionId, pAdapter->device_mode));
9369
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309370 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309371
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309372 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309373 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9375 "%s: HDD context is not valid", __func__);
9376 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309377 }
9378
9379 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9380 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9381 if (NULL == hHal)
9382 {
9383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9384 "%s: HAL context is Null!!!", __func__);
9385 return -EAGAIN;
9386 }
9387
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309388 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9389 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9390 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9391 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309392 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309393 {
9394 /* changing from big to little endian since driver
9395 * works on little endian format
9396 */
9397 tANI_U8 *p =
9398 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9399 int i;
9400
9401 for (i = 0; i < 8; i++)
9402 {
9403 p[7-i] = data->replay_ctr[i];
9404 }
9405 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309406
9407 if (TRUE == pHddCtx->hdd_wlan_suspended)
9408 {
9409 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309410 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9411 sizeof (tSirGtkOffloadParams));
9412 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309413 pAdapter->sessionId);
9414
9415 if (eHAL_STATUS_SUCCESS != status)
9416 {
9417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9418 "%s: sme_SetGTKOffload failed, returned %d",
9419 __func__, status);
9420 return status;
9421 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9423 "%s: sme_SetGTKOffload successfull", __func__);
9424 }
9425 else
9426 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9428 "%s: wlan not suspended GTKOffload request is stored",
9429 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309430 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309431
9432 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309433}
9434#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9435
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309436/*
9437 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9438 * This function is used to set access control policy
9439 */
9440static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9441 struct net_device *dev, const struct cfg80211_acl_data *params)
9442{
9443 int i;
9444 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9445 hdd_hostapd_state_t *pHostapdState;
9446 tsap_Config_t *pConfig;
9447 v_CONTEXT_t pVosContext = NULL;
9448 hdd_context_t *pHddCtx;
9449 int status;
9450
9451 ENTER();
9452
9453 if (NULL == pAdapter)
9454 {
9455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9456 "%s: HDD adapter is Null", __func__);
9457 return -ENODEV;
9458 }
9459
9460 if (NULL == params)
9461 {
9462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9463 "%s: params is Null", __func__);
9464 return -EINVAL;
9465 }
9466
9467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9468 status = wlan_hdd_validate_context(pHddCtx);
9469
9470 if (0 != status)
9471 {
9472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9473 "%s: HDD context is not valid", __func__);
9474 return status;
9475 }
9476
9477 pVosContext = pHddCtx->pvosContext;
9478 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9479
9480 if (NULL == pHostapdState)
9481 {
9482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9483 "%s: pHostapdState is Null", __func__);
9484 return -EINVAL;
9485 }
9486
9487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9488 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9489
9490 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9491 {
9492 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9493
9494 /* default value */
9495 pConfig->num_accept_mac = 0;
9496 pConfig->num_deny_mac = 0;
9497
9498 /**
9499 * access control policy
9500 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9501 * listed in hostapd.deny file.
9502 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9503 * listed in hostapd.accept file.
9504 */
9505 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9506 {
9507 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9508 }
9509 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9510 {
9511 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9512 }
9513 else
9514 {
9515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9516 "%s:Acl Policy : %d is not supported",
9517 __func__, params->acl_policy);
9518 return -ENOTSUPP;
9519 }
9520
9521 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9522 {
9523 pConfig->num_accept_mac = params->n_acl_entries;
9524 for (i = 0; i < params->n_acl_entries; i++)
9525 {
9526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9527 "** Add ACL MAC entry %i in WhiletList :"
9528 MAC_ADDRESS_STR, i,
9529 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9530
9531 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9532 sizeof(qcmacaddr));
9533 }
9534 }
9535 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9536 {
9537 pConfig->num_deny_mac = params->n_acl_entries;
9538 for (i = 0; i < params->n_acl_entries; i++)
9539 {
9540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9541 "** Add ACL MAC entry %i in BlackList :"
9542 MAC_ADDRESS_STR, i,
9543 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9544
9545 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9546 sizeof(qcmacaddr));
9547 }
9548 }
9549
9550 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9551 {
9552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9553 "%s: SAP Set Mac Acl fail", __func__);
9554 return -EINVAL;
9555 }
9556 }
9557 else
9558 {
9559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9560 "%s: Invalid device_mode = %d",
9561 __func__, pAdapter->device_mode);
9562 return -EINVAL;
9563 }
9564
9565 return 0;
9566}
9567
Leo Chang9056f462013-08-01 19:21:11 -07009568#ifdef WLAN_NL80211_TESTMODE
9569#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009570void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009571(
9572 void *pAdapter,
9573 void *indCont
9574)
9575{
Leo Changd9df8aa2013-09-26 13:32:26 -07009576 tSirLPHBInd *lphbInd;
9577 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009578
9579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009580 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009581
9582 if (NULL == indCont)
9583 {
9584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009585 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009586 return;
9587 }
9588
Leo Changd9df8aa2013-09-26 13:32:26 -07009589 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009590 skb = cfg80211_testmode_alloc_event_skb(
9591 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009592 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009593 GFP_ATOMIC);
9594 if (!skb)
9595 {
9596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9597 "LPHB timeout, NL buffer alloc fail");
9598 return;
9599 }
9600
Leo Changac3ba772013-10-07 09:47:04 -07009601 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009602 {
9603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9604 "WLAN_HDD_TM_ATTR_CMD put fail");
9605 goto nla_put_failure;
9606 }
Leo Changac3ba772013-10-07 09:47:04 -07009607 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009608 {
9609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9610 "WLAN_HDD_TM_ATTR_TYPE put fail");
9611 goto nla_put_failure;
9612 }
Leo Changac3ba772013-10-07 09:47:04 -07009613 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009614 sizeof(tSirLPHBInd), lphbInd))
9615 {
9616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9617 "WLAN_HDD_TM_ATTR_DATA put fail");
9618 goto nla_put_failure;
9619 }
Leo Chang9056f462013-08-01 19:21:11 -07009620 cfg80211_testmode_event(skb, GFP_ATOMIC);
9621 return;
9622
9623nla_put_failure:
9624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9625 "NLA Put fail");
9626 kfree_skb(skb);
9627
9628 return;
9629}
9630#endif /* FEATURE_WLAN_LPHB */
9631
9632static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9633{
9634 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9635 int err = 0;
9636#ifdef FEATURE_WLAN_LPHB
9637 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009638 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009639#endif /* FEATURE_WLAN_LPHB */
9640
9641 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9642 if (err)
9643 {
9644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9645 "%s Testmode INV ATTR", __func__);
9646 return err;
9647 }
9648
9649 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9650 {
9651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 "%s Testmode INV CMD", __func__);
9653 return -EINVAL;
9654 }
9655
9656 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9657 {
9658#ifdef FEATURE_WLAN_LPHB
9659 /* Low Power Heartbeat configuration request */
9660 case WLAN_HDD_TM_CMD_WLAN_HB:
9661 {
9662 int buf_len;
9663 void *buf;
9664 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009665 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009666
9667 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9668 {
9669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9670 "%s Testmode INV DATA", __func__);
9671 return -EINVAL;
9672 }
9673
9674 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9675 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009676
9677 hb_params_temp =(tSirLPHBReq *)buf;
9678 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9679 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9680 return -EINVAL;
9681
Leo Chang9056f462013-08-01 19:21:11 -07009682 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9683 if (NULL == hb_params)
9684 {
9685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9686 "%s Request Buffer Alloc Fail", __func__);
9687 return -EINVAL;
9688 }
9689
9690 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009691 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9692 hb_params,
9693 wlan_hdd_cfg80211_lphb_ind_handler);
9694 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009695 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9697 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009698 vos_mem_free(hb_params);
9699 }
Leo Chang9056f462013-08-01 19:21:11 -07009700 return 0;
9701 }
9702#endif /* FEATURE_WLAN_LPHB */
9703 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9705 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009706 return -EOPNOTSUPP;
9707 }
9708
9709 return err;
9710}
9711#endif /* CONFIG_NL80211_TESTMODE */
9712
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309713static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9714 struct net_device *dev,
9715 int idx, struct survey_info *survey)
9716{
9717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9718 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309719 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309720 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309721 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309722 v_S7_t snr,rssi;
9723 int status, i, j, filled = 0;
9724
9725 ENTER();
9726
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309727 if (NULL == pAdapter)
9728 {
9729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9730 "%s: HDD adapter is Null", __func__);
9731 return -ENODEV;
9732 }
9733
9734 if (NULL == wiphy)
9735 {
9736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9737 "%s: wiphy is Null", __func__);
9738 return -ENODEV;
9739 }
9740
9741 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9742 status = wlan_hdd_validate_context(pHddCtx);
9743
9744 if (0 != status)
9745 {
9746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9747 "%s: HDD context is not valid", __func__);
9748 return status;
9749 }
9750
Mihir Sheted9072e02013-08-21 17:02:29 +05309751 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9752
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309753 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309754 0 != pAdapter->survey_idx ||
9755 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309756 {
9757 /* The survey dump ops when implemented completely is expected to
9758 * return a survey of all channels and the ops is called by the
9759 * kernel with incremental values of the argument 'idx' till it
9760 * returns -ENONET. But we can only support the survey for the
9761 * operating channel for now. survey_idx is used to track
9762 * that the ops is called only once and then return -ENONET for
9763 * the next iteration
9764 */
9765 pAdapter->survey_idx = 0;
9766 return -ENONET;
9767 }
9768
9769 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9770
9771 wlan_hdd_get_snr(pAdapter, &snr);
9772 wlan_hdd_get_rssi(pAdapter, &rssi);
9773
9774 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9775 hdd_wlan_get_freq(channel, &freq);
9776
9777
9778 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9779 {
9780 if (NULL == wiphy->bands[i])
9781 {
9782 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9783 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9784 continue;
9785 }
9786
9787 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9788 {
9789 struct ieee80211_supported_band *band = wiphy->bands[i];
9790
9791 if (band->channels[j].center_freq == (v_U16_t)freq)
9792 {
9793 survey->channel = &band->channels[j];
9794 /* The Rx BDs contain SNR values in dB for the received frames
9795 * while the supplicant expects noise. So we calculate and
9796 * return the value of noise (dBm)
9797 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9798 */
9799 survey->noise = rssi - snr;
9800 survey->filled = SURVEY_INFO_NOISE_DBM;
9801 filled = 1;
9802 }
9803 }
9804 }
9805
9806 if (filled)
9807 pAdapter->survey_idx = 1;
9808 else
9809 {
9810 pAdapter->survey_idx = 0;
9811 return -ENONET;
9812 }
9813
9814 return 0;
9815}
9816
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309817/*
9818 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9819 * this is called when cfg80211 driver resume
9820 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9821 */
9822int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9823{
9824 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9825 hdd_adapter_t *pAdapter;
9826 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9827 VOS_STATUS status = VOS_STATUS_SUCCESS;
9828
9829 ENTER();
9830
9831 if ( NULL == pHddCtx )
9832 {
9833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9834 "%s: HddCtx validation failed", __func__);
9835 return 0;
9836 }
9837
9838 if (pHddCtx->isLogpInProgress)
9839 {
9840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9841 "%s: LOGP in Progress. Ignore!!!", __func__);
9842 return 0;
9843 }
9844
Mihir Shete18156292014-03-11 15:38:30 +05309845 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309846 {
9847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9848 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9849 return 0;
9850 }
9851
9852 spin_lock(&pHddCtx->schedScan_lock);
9853 pHddCtx->isWiphySuspended = FALSE;
9854 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9855 {
9856 spin_unlock(&pHddCtx->schedScan_lock);
9857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9858 "%s: Return resume is not due to PNO indication", __func__);
9859 return 0;
9860 }
9861 // Reset flag to avoid updatating cfg80211 data old results again
9862 pHddCtx->isSchedScanUpdatePending = FALSE;
9863 spin_unlock(&pHddCtx->schedScan_lock);
9864
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309865
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309866 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9867
9868 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9869 {
9870 pAdapter = pAdapterNode->pAdapter;
9871 if ( (NULL != pAdapter) &&
9872 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9873 {
9874 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309875 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9877 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309878 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309879 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309880 {
9881 /* Acquire wakelock to handle the case where APP's tries to
9882 * suspend immediately after updating the scan results. Whis
9883 * results in app's is in suspended state and not able to
9884 * process the connect request to AP
9885 */
9886 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309887 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309888 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309889
9890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9891 "%s : cfg80211 scan result database updated", __func__);
9892
9893 return 0;
9894
9895 }
9896 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9897 pAdapterNode = pNext;
9898 }
9899
9900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9901 "%s: Failed to find Adapter", __func__);
9902 return 0;
9903}
9904
9905/*
9906 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9907 * this is called when cfg80211 driver suspends
9908 */
9909int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9910 struct cfg80211_wowlan *wow)
9911{
9912 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9913
9914 ENTER();
9915 if (NULL == pHddCtx)
9916 {
9917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9918 "%s: HddCtx validation failed", __func__);
9919 return 0;
9920 }
9921
9922 pHddCtx->isWiphySuspended = TRUE;
9923
9924 EXIT();
9925
9926 return 0;
9927}
9928
Jeff Johnson295189b2012-06-20 16:38:30 -07009929/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309930static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009931{
9932 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9933 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9934 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9935 .change_station = wlan_hdd_change_station,
9936#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9937 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9938 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9939 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009940#else
9941 .start_ap = wlan_hdd_cfg80211_start_ap,
9942 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9943 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009944#endif
9945 .change_bss = wlan_hdd_cfg80211_change_bss,
9946 .add_key = wlan_hdd_cfg80211_add_key,
9947 .get_key = wlan_hdd_cfg80211_get_key,
9948 .del_key = wlan_hdd_cfg80211_del_key,
9949 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009950#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 .scan = wlan_hdd_cfg80211_scan,
9954 .connect = wlan_hdd_cfg80211_connect,
9955 .disconnect = wlan_hdd_cfg80211_disconnect,
9956 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9957 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9958 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9959 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9960 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9962 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +05309963 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -07009964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9965 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9966 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9967 .set_txq_params = wlan_hdd_set_txq_params,
9968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 .get_station = wlan_hdd_cfg80211_get_station,
9970 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9971 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009972 .add_station = wlan_hdd_cfg80211_add_station,
9973#ifdef FEATURE_WLAN_LFR
9974 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9975 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9976 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9977#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009978#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9979 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9980#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009981#ifdef FEATURE_WLAN_TDLS
9982 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9983 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9984#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309985#ifdef WLAN_FEATURE_GTK_OFFLOAD
9986 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9987#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309988#ifdef FEATURE_WLAN_SCAN_PNO
9989 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9990 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9991#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309992 .resume = wlan_hdd_cfg80211_resume_wlan,
9993 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309994 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009995#ifdef WLAN_NL80211_TESTMODE
9996 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9997#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309998 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009999};
10000