blob: f7664390de5eb7457218b698da77fc8a5b3a5cca [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
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530168static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700169{
170 WLAN_CIPHER_SUITE_WEP40,
171 WLAN_CIPHER_SUITE_WEP104,
172 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800173#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700174#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
175 WLAN_CIPHER_SUITE_KRK,
176 WLAN_CIPHER_SUITE_CCMP,
177#else
178 WLAN_CIPHER_SUITE_CCMP,
179#endif
180#ifdef FEATURE_WLAN_WAPI
181 WLAN_CIPHER_SUITE_SMS4,
182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700183#ifdef WLAN_FEATURE_11W
184 WLAN_CIPHER_SUITE_AES_CMAC,
185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700186};
187
188static inline int is_broadcast_ether_addr(const u8 *addr)
189{
190 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
191 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
192}
193
194static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530195{
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 HDD2GHZCHAN(2412, 1, 0) ,
197 HDD2GHZCHAN(2417, 2, 0) ,
198 HDD2GHZCHAN(2422, 3, 0) ,
199 HDD2GHZCHAN(2427, 4, 0) ,
200 HDD2GHZCHAN(2432, 5, 0) ,
201 HDD2GHZCHAN(2437, 6, 0) ,
202 HDD2GHZCHAN(2442, 7, 0) ,
203 HDD2GHZCHAN(2447, 8, 0) ,
204 HDD2GHZCHAN(2452, 9, 0) ,
205 HDD2GHZCHAN(2457, 10, 0) ,
206 HDD2GHZCHAN(2462, 11, 0) ,
207 HDD2GHZCHAN(2467, 12, 0) ,
208 HDD2GHZCHAN(2472, 13, 0) ,
209 HDD2GHZCHAN(2484, 14, 0) ,
210};
211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
213{
214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2437, 6, 0) ,
216 HDD2GHZCHAN(2462, 11, 0) ,
217};
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219static struct ieee80211_channel hdd_channels_5_GHZ[] =
220{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700221 HDD5GHZCHAN(4920, 240, 0) ,
222 HDD5GHZCHAN(4940, 244, 0) ,
223 HDD5GHZCHAN(4960, 248, 0) ,
224 HDD5GHZCHAN(4980, 252, 0) ,
225 HDD5GHZCHAN(5040, 208, 0) ,
226 HDD5GHZCHAN(5060, 212, 0) ,
227 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5180, 36, 0) ,
229 HDD5GHZCHAN(5200, 40, 0) ,
230 HDD5GHZCHAN(5220, 44, 0) ,
231 HDD5GHZCHAN(5240, 48, 0) ,
232 HDD5GHZCHAN(5260, 52, 0) ,
233 HDD5GHZCHAN(5280, 56, 0) ,
234 HDD5GHZCHAN(5300, 60, 0) ,
235 HDD5GHZCHAN(5320, 64, 0) ,
236 HDD5GHZCHAN(5500,100, 0) ,
237 HDD5GHZCHAN(5520,104, 0) ,
238 HDD5GHZCHAN(5540,108, 0) ,
239 HDD5GHZCHAN(5560,112, 0) ,
240 HDD5GHZCHAN(5580,116, 0) ,
241 HDD5GHZCHAN(5600,120, 0) ,
242 HDD5GHZCHAN(5620,124, 0) ,
243 HDD5GHZCHAN(5640,128, 0) ,
244 HDD5GHZCHAN(5660,132, 0) ,
245 HDD5GHZCHAN(5680,136, 0) ,
246 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800247#ifdef FEATURE_WLAN_CH144
248 HDD5GHZCHAN(5720,144, 0) ,
249#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDD5GHZCHAN(5745,149, 0) ,
251 HDD5GHZCHAN(5765,153, 0) ,
252 HDD5GHZCHAN(5785,157, 0) ,
253 HDD5GHZCHAN(5805,161, 0) ,
254 HDD5GHZCHAN(5825,165, 0) ,
255};
256
257static struct ieee80211_rate g_mode_rates[] =
258{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530259 HDD_G_MODE_RATETAB(10, 0x1, 0),
260 HDD_G_MODE_RATETAB(20, 0x2, 0),
261 HDD_G_MODE_RATETAB(55, 0x4, 0),
262 HDD_G_MODE_RATETAB(110, 0x8, 0),
263 HDD_G_MODE_RATETAB(60, 0x10, 0),
264 HDD_G_MODE_RATETAB(90, 0x20, 0),
265 HDD_G_MODE_RATETAB(120, 0x40, 0),
266 HDD_G_MODE_RATETAB(180, 0x80, 0),
267 HDD_G_MODE_RATETAB(240, 0x100, 0),
268 HDD_G_MODE_RATETAB(360, 0x200, 0),
269 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271};
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273static struct ieee80211_rate a_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
283};
284
285static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
286{
287 .channels = hdd_channels_2_4_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
289 .band = IEEE80211_BAND_2GHZ,
290 .bitrates = g_mode_rates,
291 .n_bitrates = g_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
297 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
298 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
299 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
300 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
301 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
302};
303
Jeff Johnson295189b2012-06-20 16:38:30 -0700304static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
305{
306 .channels = hdd_social_channels_2_4_GHZ,
307 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
308 .band = IEEE80211_BAND_2GHZ,
309 .bitrates = g_mode_rates,
310 .n_bitrates = g_mode_rates_size,
311 .ht_cap.ht_supported = 1,
312 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
313 | IEEE80211_HT_CAP_GRN_FLD
314 | IEEE80211_HT_CAP_DSSSCCK40
315 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
316 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
317 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
318 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
319 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
320 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
321};
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
324{
325 .channels = hdd_channels_5_GHZ,
326 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
327 .band = IEEE80211_BAND_5GHZ,
328 .bitrates = a_mode_rates,
329 .n_bitrates = a_mode_rates_size,
330 .ht_cap.ht_supported = 1,
331 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
332 | IEEE80211_HT_CAP_GRN_FLD
333 | IEEE80211_HT_CAP_DSSSCCK40
334 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
335 | IEEE80211_HT_CAP_SGI_40
336 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
337 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
338 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
339 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
340 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
341 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
342};
343
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530344/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 TX/RX direction for each kind of interface */
346static const struct ieee80211_txrx_stypes
347wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
348 [NL80211_IFTYPE_STATION] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_AP] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700363 [NL80211_IFTYPE_ADHOC] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ) |
368 BIT(SIR_MAC_MGMT_DISASSOC) |
369 BIT(SIR_MAC_MGMT_AUTH) |
370 BIT(SIR_MAC_MGMT_DEAUTH) |
371 BIT(SIR_MAC_MGMT_ACTION),
372 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 [NL80211_IFTYPE_P2P_CLIENT] = {
374 .tx = 0xffff,
375 .rx = BIT(SIR_MAC_MGMT_ACTION) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ),
377 },
378 [NL80211_IFTYPE_P2P_GO] = {
379 /* This is also same as for SoftAP */
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389};
390
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392static const struct ieee80211_iface_limit
393wlan_hdd_iface_limit[] = {
394 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /* max = 3 ; Our driver create two interfaces during driver init
396 * wlan0 and p2p0 interfaces. p2p0 is considered as station
397 * interface until a group is formed. In JB architecture, once the
398 * group is formed, interface type of p2p0 is changed to P2P GO or
399 * Client.
400 * When supplicant remove the group, it first issue a set interface
401 * cmd to change the mode back to Station. In JB this works fine as
402 * we advertize two station type interface during driver init.
403 * Some vendors create separate interface for P2P GO/Client,
404 * after group formation(Third one). But while group remove
405 * supplicant first tries to change the mode(3rd interface) to STATION
406 * But as we advertized only two sta type interfaces nl80211 was
407 * returning error for the third one which was leading to failure in
408 * delete interface. Ideally while removing the group, supplicant
409 * should not try to change the 3rd interface mode to Station type.
410 * Till we get a fix in wpa_supplicant, we advertize max STA
411 * interface type to 3
412 */
413 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .types = BIT(NL80211_IFTYPE_STATION),
415 },
416 {
417 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700418 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 },
420 {
421 .max = 1,
422 .types = BIT(NL80211_IFTYPE_P2P_GO) |
423 BIT(NL80211_IFTYPE_P2P_CLIENT),
424 },
425};
426
427/* By default, only single channel concurrency is allowed */
428static struct ieee80211_iface_combination
429wlan_hdd_iface_combination = {
430 .limits = wlan_hdd_iface_limit,
431 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800432 /*
433 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
434 * and p2p0 interfaces during driver init
435 * Some vendors create separate interface for P2P operations.
436 * wlan0: STA interface
437 * p2p0: P2P Device interface, action frames goes
438 * through this interface.
439 * p2p-xx: P2P interface, After GO negotiation this interface is
440 * created for p2p operations(GO/CLIENT interface).
441 */
442 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800443 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
444 .beacon_int_infra_match = false,
445};
446#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800447
Jeff Johnson295189b2012-06-20 16:38:30 -0700448static struct cfg80211_ops wlan_hdd_cfg80211_ops;
449
450/* Data rate 100KBPS based on IE Index */
451struct index_data_rate_type
452{
453 v_U8_t beacon_rate_index;
454 v_U16_t supported_rate[4];
455};
456
457/* 11B, 11G Rate table include Basic rate and Extended rate
458 The IDX field is the rate index
459 The HI field is the rate when RSSI is strong or being ignored
460 (in this case we report actual rate)
461 The MID field is the rate when RSSI is moderate
462 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
463 The LO field is the rate when RSSI is low
464 (in this case we don't report rates, actual current rate used)
465 */
466static const struct
467{
468 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700470} supported_data_rate[] =
471{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700472/* IDX HI HM LM LO (RSSI-based index */
473 {2, { 10, 10, 10, 0}},
474 {4, { 20, 20, 10, 0}},
475 {11, { 55, 20, 10, 0}},
476 {12, { 60, 55, 20, 0}},
477 {18, { 90, 55, 20, 0}},
478 {22, {110, 55, 20, 0}},
479 {24, {120, 90, 60, 0}},
480 {36, {180, 120, 60, 0}},
481 {44, {220, 180, 60, 0}},
482 {48, {240, 180, 90, 0}},
483 {66, {330, 180, 90, 0}},
484 {72, {360, 240, 90, 0}},
485 {96, {480, 240, 120, 0}},
486 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700487};
488
489/* MCS Based rate table */
490static struct index_data_rate_type supported_mcs_rate[] =
491{
492/* MCS L20 L40 S20 S40 */
493 {0, {65, 135, 72, 150}},
494 {1, {130, 270, 144, 300}},
495 {2, {195, 405, 217, 450}},
496 {3, {260, 540, 289, 600}},
497 {4, {390, 810, 433, 900}},
498 {5, {520, 1080, 578, 1200}},
499 {6, {585, 1215, 650, 1350}},
500 {7, {650, 1350, 722, 1500}}
501};
502
Leo Chang6f8870f2013-03-26 18:11:36 -0700503#ifdef WLAN_FEATURE_11AC
504
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530505#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700506
507struct index_vht_data_rate_type
508{
509 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510 v_U16_t supported_VHT80_rate[2];
511 v_U16_t supported_VHT40_rate[2];
512 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700513};
514
515typedef enum
516{
517 DATA_RATE_11AC_MAX_MCS_7,
518 DATA_RATE_11AC_MAX_MCS_8,
519 DATA_RATE_11AC_MAX_MCS_9,
520 DATA_RATE_11AC_MAX_MCS_NA
521} eDataRate11ACMaxMcs;
522
523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
Jeff Johnson295189b2012-06-20 16:38:30 -0700540extern struct net_device_ops net_ops_struct;
541
Leo Chang9056f462013-08-01 19:21:11 -0700542#ifdef WLAN_NL80211_TESTMODE
543enum wlan_hdd_tm_attr
544{
545 WLAN_HDD_TM_ATTR_INVALID = 0,
546 WLAN_HDD_TM_ATTR_CMD = 1,
547 WLAN_HDD_TM_ATTR_DATA = 2,
548 WLAN_HDD_TM_ATTR_TYPE = 3,
549 /* keep last */
550 WLAN_HDD_TM_ATTR_AFTER_LAST,
551 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
552};
553
554enum wlan_hdd_tm_cmd
555{
556 WLAN_HDD_TM_CMD_WLAN_HB = 1,
557};
558
559#define WLAN_HDD_TM_DATA_MAX_LEN 5000
560
561static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
562{
563 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
564 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
565 .len = WLAN_HDD_TM_DATA_MAX_LEN },
566};
567#endif /* WLAN_NL80211_TESTMODE */
568
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800569#ifdef FEATURE_WLAN_CH_AVOID
570/*
571 * FUNCTION: wlan_hdd_send_avoid_freq_event
572 * This is called when wlan driver needs to send vendor specific
573 * avoid frequency range event to userspace
574 */
575int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
576 tHddAvoidFreqList *pAvoidFreqList)
577{
578 struct sk_buff *vendor_event;
579
580 ENTER();
581
582 if (!pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
585 "%s: HDD context is null", __func__);
586 return -1;
587 }
588
589 if (!pAvoidFreqList)
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
592 "%s: pAvoidFreqList is null", __func__);
593 return -1;
594 }
595
596 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
597 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530598 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800599 GFP_KERNEL);
600 if (!vendor_event)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: cfg80211_vendor_event_alloc failed", __func__);
604 return -1;
605 }
606
607 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
608 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
609
610 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
611
612 EXIT();
613 return 0;
614}
615#endif /* FEATURE_WLAN_CH_AVOID */
616
Sunil Duttc69bccb2014-05-26 21:30:20 +0530617#ifdef WLAN_FEATURE_LINK_LAYER_STATS
618
619static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
620 struct sk_buff *vendor_event)
621{
622 if (nla_put_u8(vendor_event,
623 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
624 stats->rate.preamble) ||
625 nla_put_u8(vendor_event,
626 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
627 stats->rate.nss) ||
628 nla_put_u8(vendor_event,
629 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
630 stats->rate.bw) ||
631 nla_put_u8(vendor_event,
632 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
633 stats->rate.rateMcsIdx) ||
634 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
635 stats->rate.bitrate ) ||
636 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
637 stats->txMpdu ) ||
638 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
639 stats->rxMpdu ) ||
640 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
641 stats->mpduLost ) ||
642 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
643 stats->retries) ||
644 nla_put_u32(vendor_event,
645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
646 stats->retriesShort ) ||
647 nla_put_u32(vendor_event,
648 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
649 stats->retriesLong))
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("QCA_WLAN_VENDOR_ATTR put fail"));
653 return FALSE;
654 }
655 return TRUE;
656}
657
658static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
659 struct sk_buff *vendor_event)
660{
661 u32 i = 0;
662 struct nlattr *rateInfo;
663 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
664 stats->type) ||
665 nla_put(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
667 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
668 nla_put_u32(vendor_event,
669 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
670 stats->capabilities) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
673 stats->numRate))
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("QCA_WLAN_VENDOR_ATTR put fail"));
677 goto error;
678 }
679
680 rateInfo = nla_nest_start(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
682 for (i = 0; i < stats->numRate; i++)
683 {
684 struct nlattr *rates;
685 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
686 stats->rateStats +
687 (i * sizeof(tSirWifiRateStat)));
688 rates = nla_nest_start(vendor_event, i);
689
690 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
691 {
692 hddLog(VOS_TRACE_LEVEL_ERROR,
693 FL("QCA_WLAN_VENDOR_ATTR put fail"));
694 return FALSE;
695 }
696 nla_nest_end(vendor_event, rates);
697 }
698 nla_nest_end(vendor_event, rateInfo);
699
700 return TRUE;
701error:
702 return FALSE;
703}
704
705static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
706 struct sk_buff *vendor_event)
707{
708 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
709 stats->ac ) ||
710 nla_put_u32(vendor_event,
711 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
712 stats->txMpdu ) ||
713 nla_put_u32(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
715 stats->rxMpdu ) ||
716 nla_put_u32(vendor_event,
717 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
718 stats->txMcast ) ||
719 nla_put_u32(vendor_event,
720 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
721 stats->rxMcast ) ||
722 nla_put_u32(vendor_event,
723 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
724 stats->rxAmpdu ) ||
725 nla_put_u32(vendor_event,
726 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
727 stats->txAmpdu ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
730 stats->mpduLost )||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
733 stats->retries ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
736 stats->retriesShort ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
739 stats->retriesLong ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
742 stats->contentionTimeMin ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
745 stats->contentionTimeMax ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
748 stats->contentionTimeAvg ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
751 stats->contentionNumSamples ))
752 {
753 hddLog(VOS_TRACE_LEVEL_ERROR,
754 FL("QCA_WLAN_VENDOR_ATTR put fail") );
755 return FALSE;
756 }
757 return TRUE;
758}
759
760static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
761 struct sk_buff *vendor_event)
762{
763 if (nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
765 nla_put(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
767 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
770 stats->state ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
773 stats->roaming ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
776 stats->capabilities ) ||
777 nla_put(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
779 strlen(stats->ssid), stats->ssid) ||
780 nla_put(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
782 WNI_CFG_BSSID_LEN, stats->bssid) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
785 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
786 nla_put(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
788 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
789 )
790 {
791 hddLog(VOS_TRACE_LEVEL_ERROR,
792 FL("QCA_WLAN_VENDOR_ATTR put fail") );
793 return FALSE;
794 }
795 return TRUE;
796}
797
798static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
799 struct sk_buff *vendor_event)
800{
801 int i = 0;
802 struct nlattr *wmmInfo;
803 if (FALSE == put_wifi_interface_info(
804 &pWifiIfaceStat->info,
805 vendor_event))
806 {
807 hddLog(VOS_TRACE_LEVEL_ERROR,
808 FL("QCA_WLAN_VENDOR_ATTR put fail") );
809 return FALSE;
810
811 }
812
813 if (nla_put_u32(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
815 pWifiIfaceStat->beaconRx) ||
816 nla_put_u32(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
818 pWifiIfaceStat->mgmtRx) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
821 pWifiIfaceStat->mgmtActionRx) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
824 pWifiIfaceStat->mgmtActionTx) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
827 pWifiIfaceStat->rssiMgmt) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
830 pWifiIfaceStat->rssiData) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
833 pWifiIfaceStat->rssiAck))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail"));
837 return FALSE;
838 }
839
840 wmmInfo = nla_nest_start(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
842 for (i = 0; i < WIFI_AC_MAX; i++)
843 {
844 struct nlattr *wmmStats;
845 wmmStats = nla_nest_start(vendor_event, i);
846 if (FALSE == put_wifi_wmm_ac_stat(
847 &pWifiIfaceStat->AccessclassStats[i],
848 vendor_event))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
852 return FALSE;
853 }
854
855 nla_nest_end(vendor_event, wmmStats);
856 }
857 nla_nest_end(vendor_event, wmmInfo);
858 return TRUE;
859}
860
861static tSirWifiInterfaceMode
862 hdd_map_device_to_ll_iface_mode ( int deviceMode )
863{
864 switch (deviceMode)
865 {
866 case WLAN_HDD_INFRA_STATION:
867 return WIFI_INTERFACE_STA;
868 case WLAN_HDD_SOFTAP:
869 return WIFI_INTERFACE_SOFTAP;
870 case WLAN_HDD_P2P_CLIENT:
871 return WIFI_INTERFACE_P2P_CLIENT;
872 case WLAN_HDD_P2P_GO:
873 return WIFI_INTERFACE_P2P_GO;
874 case WLAN_HDD_IBSS:
875 return WIFI_INTERFACE_IBSS;
876 default:
877 /* Return Interface Mode as STA for all the unsupported modes */
878 return WIFI_INTERFACE_STA;
879 }
880}
881
882static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
883 tpSirWifiInterfaceInfo pInfo)
884{
885 v_U8_t *staMac = NULL;
886 hdd_station_ctx_t *pHddStaCtx;
887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
888 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
889
890 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
891
892 vos_mem_copy(pInfo->macAddr,
893 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
894
895 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
896 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
897 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
898 {
899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
900 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
901 {
902 pInfo->state = WIFI_DISCONNECTED;
903 }
904 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
905 {
906 hddLog(VOS_TRACE_LEVEL_ERROR,
907 "%s: Session ID %d, Connection is in progress", __func__,
908 pAdapter->sessionId);
909 pInfo->state = WIFI_ASSOCIATING;
910 }
911 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
912 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
913 {
914 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
915 hddLog(VOS_TRACE_LEVEL_ERROR,
916 "%s: client " MAC_ADDRESS_STR
917 " is in the middle of WPS/EAPOL exchange.", __func__,
918 MAC_ADDR_ARRAY(staMac));
919 pInfo->state = WIFI_AUTHENTICATING;
920 }
921 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
922 {
923 pInfo->state = WIFI_ASSOCIATED;
924 vos_mem_copy(pInfo->bssid,
925 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
926 vos_mem_copy(pInfo->ssid,
927 pHddStaCtx->conn_info.SSID.SSID.ssId,
928 pHddStaCtx->conn_info.SSID.SSID.length);
929 //NULL Terminate the string.
930 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
931 }
932 }
933 vos_mem_copy(pInfo->countryStr,
934 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
935
936 vos_mem_copy(pInfo->apCountryStr,
937 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
938
939 return TRUE;
940}
941
942/*
943 * hdd_link_layer_process_peer_stats () - This function is called after
944 * receiving Link Layer Peer statistics from FW.This function converts
945 * the firmware data to the NL data and sends the same to the kernel/upper
946 * layers.
947 */
948static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
949 v_VOID_t *pData)
950{
951 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
952 tpSirWifiRateStat pWifiRateStat;
953 tpSirWifiPeerStat pWifiPeerStat;
954 tpSirWifiPeerInfo pWifiPeerInfo;
955 struct nlattr *peerInfo;
956 struct sk_buff *vendor_event;
957 int status, i;
958
959 status = wlan_hdd_validate_context(pHddCtx);
960 if (0 != status)
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("HDD context is not valid") );
964 return;
965 }
966
967 pWifiPeerStat = (tpSirWifiPeerStat) pData;
968
969 hddLog(VOS_TRACE_LEVEL_INFO,
970 "LL_STATS_PEER_ALL : numPeers %u",
971 pWifiPeerStat->numPeers);
972 {
973 for (i = 0; i < pWifiPeerStat->numPeers; i++)
974 {
975 pWifiPeerInfo = (tpSirWifiPeerInfo)
976 ((uint8 *)pWifiPeerStat->peerInfo +
977 ( i * sizeof(tSirWifiPeerInfo)));
978
979 hddLog(VOS_TRACE_LEVEL_INFO,
980 " %d) LL_STATS Channel Stats "
981 " Peer Type %u "
982 " peerMacAddress %pM "
983 " capabilities 0x%x "
984 " numRate %u ",
985 i,
986 pWifiPeerInfo->type,
987 pWifiPeerInfo->peerMacAddress,
988 pWifiPeerInfo->capabilities,
989 pWifiPeerInfo->numRate);
990 {
991 int j;
992 for (j = 0; j < pWifiPeerInfo->numRate; j++)
993 {
994 pWifiRateStat = (tpSirWifiRateStat)
995 ((tANI_U8 *) pWifiPeerInfo->rateStats +
996 ( j * sizeof(tSirWifiRateStat)));
997
998 hddLog(VOS_TRACE_LEVEL_INFO,
999 " peer Rate Stats "
1000 " preamble %u "
1001 " nss %u "
1002 " bw %u "
1003 " rateMcsIdx %u "
1004 " reserved %u "
1005 " bitrate %u "
1006 " txMpdu %u "
1007 " rxMpdu %u "
1008 " mpduLost %u "
1009 " retries %u "
1010 " retriesShort %u "
1011 " retriesLong %u",
1012 pWifiRateStat->rate.preamble,
1013 pWifiRateStat->rate.nss,
1014 pWifiRateStat->rate.bw,
1015 pWifiRateStat->rate.rateMcsIdx,
1016 pWifiRateStat->rate.reserved,
1017 pWifiRateStat->rate.bitrate,
1018 pWifiRateStat->txMpdu,
1019 pWifiRateStat->rxMpdu,
1020 pWifiRateStat->mpduLost,
1021 pWifiRateStat->retries,
1022 pWifiRateStat->retriesShort,
1023 pWifiRateStat->retriesLong);
1024 }
1025 }
1026 }
1027 }
1028
1029 /*
1030 * Allocate a size of 4096 for the peer stats comprising
1031 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1032 * sizeof (tSirWifiRateStat).Each field is put with an
1033 * NL attribute.The size of 4096 is considered assuming
1034 * that number of rates shall not exceed beyond 50 with
1035 * the sizeof (tSirWifiRateStat) being 32.
1036 */
1037 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1038 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1039 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1040 GFP_KERNEL);
1041 if (!vendor_event)
1042 {
1043 hddLog(VOS_TRACE_LEVEL_ERROR,
1044 "%s: cfg80211_vendor_event_alloc failed",
1045 __func__);
1046 return;
1047 }
1048 if (nla_put_u32(vendor_event,
1049 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1050 pWifiPeerStat->numPeers))
1051 {
1052 hddLog(VOS_TRACE_LEVEL_ERROR,
1053 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1054 kfree_skb(vendor_event);
1055 return;
1056 }
1057
1058 peerInfo = nla_nest_start(vendor_event,
1059 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1060
1061 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1062 pWifiPeerStat->peerInfo);
1063
1064 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1065 {
1066 struct nlattr *peers = nla_nest_start(vendor_event, i);
1067 int numRate = pWifiPeerInfo->numRate;
1068
1069 if (FALSE == put_wifi_peer_info(
1070 pWifiPeerInfo, vendor_event))
1071 {
1072 hddLog(VOS_TRACE_LEVEL_ERROR,
1073 "%s: put_wifi_peer_info put fail", __func__);
1074 kfree_skb(vendor_event);
1075 return;
1076 }
1077
1078 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1079 pWifiPeerStat->peerInfo +
1080 (i * sizeof(tSirWifiPeerInfo)) +
1081 (numRate * sizeof (tSirWifiRateStat)));
1082 nla_nest_end(vendor_event, peers);
1083 }
1084 nla_nest_end(vendor_event, peerInfo);
1085 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1086}
1087
1088/*
1089 * hdd_link_layer_process_iface_stats () - This function is called after
1090 * receiving Link Layer Interface statistics from FW.This function converts
1091 * the firmware data to the NL data and sends the same to the kernel/upper
1092 * layers.
1093 */
1094static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1095 v_VOID_t *pData)
1096{
1097 tpSirWifiIfaceStat pWifiIfaceStat;
1098 struct sk_buff *vendor_event;
1099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1100 int status;
1101
1102 status = wlan_hdd_validate_context(pHddCtx);
1103 if (0 != status)
1104 {
1105 hddLog(VOS_TRACE_LEVEL_ERROR,
1106 FL("HDD context is not valid") );
1107 return;
1108 }
1109 /*
1110 * Allocate a size of 4096 for the interface stats comprising
1111 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1112 * assuming that all these fit with in the limit.Please take
1113 * a call on the limit based on the data requirements on
1114 * interface statistics.
1115 */
1116 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1117 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1118 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1119 GFP_KERNEL);
1120 if (!vendor_event)
1121 {
1122 hddLog(VOS_TRACE_LEVEL_ERROR,
1123 FL("cfg80211_vendor_event_alloc failed") );
1124 return;
1125 }
1126
1127 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1128
1129 hddLog(VOS_TRACE_LEVEL_INFO,
1130 "WMI_LINK_STATS_IFACE Data");
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 "LL_STATS_IFACE: "
1134 " Mode %u "
1135 " MAC %pM "
1136 " State %u "
1137 " Roaming %u "
1138 " capabilities 0x%x "
1139 " SSID %s "
1140 " BSSID %pM",
1141 pWifiIfaceStat->info.mode,
1142 pWifiIfaceStat->info.macAddr,
1143 pWifiIfaceStat->info.state,
1144 pWifiIfaceStat->info.roaming,
1145 pWifiIfaceStat->info.capabilities,
1146 pWifiIfaceStat->info.ssid,
1147 pWifiIfaceStat->info.bssid);
1148
1149 hddLog(VOS_TRACE_LEVEL_INFO,
1150 " AP country str: %c%c%c",
1151 pWifiIfaceStat->info.apCountryStr[0],
1152 pWifiIfaceStat->info.apCountryStr[1],
1153 pWifiIfaceStat->info.apCountryStr[2]);
1154
1155
1156 hddLog(VOS_TRACE_LEVEL_INFO,
1157 " Country Str Association: %c%c%c",
1158 pWifiIfaceStat->info.countryStr[0],
1159 pWifiIfaceStat->info.countryStr[1],
1160 pWifiIfaceStat->info.countryStr[2]);
1161
1162 hddLog(VOS_TRACE_LEVEL_INFO,
1163 " beaconRx %u "
1164 " mgmtRx %u "
1165 " mgmtActionRx %u "
1166 " mgmtActionTx %u "
1167 " rssiMgmt %u "
1168 " rssiData %u "
1169 " rssiAck %u",
1170 pWifiIfaceStat->beaconRx,
1171 pWifiIfaceStat->mgmtRx,
1172 pWifiIfaceStat->mgmtActionRx,
1173 pWifiIfaceStat->mgmtActionTx,
1174 pWifiIfaceStat->rssiMgmt,
1175 pWifiIfaceStat->rssiData,
1176 pWifiIfaceStat->rssiAck );
1177
1178
1179 {
1180 int i;
1181 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_INFO,
1184
1185 " %d) LL_STATS IFACE: "
1186 " ac: %u txMpdu: %u "
1187 " rxMpdu: %u txMcast: %u "
1188 " rxMcast: %u rxAmpdu: %u "
1189 " txAmpdu: %u mpduLost: %u "
1190 " retries: %u retriesShort: %u "
1191 " retriesLong: %u contentionTimeMin: %u "
1192 " contentionTimeMax: %u contentionTimeAvg: %u "
1193 " contentionNumSamples: %u",
1194 i,
1195 pWifiIfaceStat->AccessclassStats[i].ac,
1196 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1197 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1198 pWifiIfaceStat->AccessclassStats[i].txMcast,
1199 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1200 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1201 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1202 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1203 pWifiIfaceStat->AccessclassStats[i].retries,
1204 pWifiIfaceStat->
1205 AccessclassStats[i].retriesShort,
1206 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1207 pWifiIfaceStat->
1208 AccessclassStats[i].contentionTimeMin,
1209 pWifiIfaceStat->
1210 AccessclassStats[i].contentionTimeMax,
1211 pWifiIfaceStat->
1212 AccessclassStats[i].contentionTimeAvg,
1213 pWifiIfaceStat->
1214 AccessclassStats[i].contentionNumSamples);
1215
1216 }
1217 }
1218
1219 if (FALSE == hdd_get_interface_info( pAdapter,
1220 &pWifiIfaceStat->info))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 FL("hdd_get_interface_info get fail") );
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1229 vendor_event))
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("put_wifi_iface_stats fail") );
1233 kfree_skb(vendor_event);
1234 return;
1235 }
1236 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1237}
1238
1239/*
1240 * hdd_link_layer_process_radio_stats () - This function is called after
1241 * receiving Link Layer Radio statistics from FW.This function converts
1242 * the firmware data to the NL data and sends the same to the kernel/upper
1243 * layers.
1244 */
1245static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1246 v_VOID_t *pData)
1247{
1248 int status, i;
1249 tpSirWifiRadioStat pWifiRadioStat;
1250 tpSirWifiChannelStats pWifiChannelStats;
1251 struct sk_buff *vendor_event;
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1253 struct nlattr *chList;
1254
1255 status = wlan_hdd_validate_context(pHddCtx);
1256 if (0 != status)
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("HDD context is not valid") );
1260 return;
1261 }
1262 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1263
1264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 "LL_STATS_RADIO"
1266 " radio is %d onTime is %u "
1267 " txTime is %u rxTime is %u "
1268 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301269 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 " onTimePnoScan is %u onTimeHs20 is %u "
1271 " numChannels is %u",
1272 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1273 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1274 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301275 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301276 pWifiRadioStat->onTimeRoamScan,
1277 pWifiRadioStat->onTimePnoScan,
1278 pWifiRadioStat->onTimeHs20,
1279 pWifiRadioStat->numChannels);
1280 /*
1281 * Allocate a size of 4096 for the Radio stats comprising
1282 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1283 * (tSirWifiChannelStats).Each channel data is put with an
1284 * NL attribute.The size of 4096 is considered assuming that
1285 * number of channels shall not exceed beyond 60 with the
1286 * sizeof (tSirWifiChannelStats) being 24 bytes.
1287 */
1288
1289 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1290 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1291 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1292 GFP_KERNEL);
1293
1294 if (!vendor_event)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 FL("cfg80211_vendor_event_alloc failed") );
1298 return;
1299 }
1300
1301 if (nla_put_u32(vendor_event,
1302 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1303 pWifiRadioStat->radio) ||
1304 nla_put_u32(vendor_event,
1305 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1306 pWifiRadioStat->onTime) ||
1307 nla_put_u32(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1309 pWifiRadioStat->txTime) ||
1310 nla_put_u32(vendor_event,
1311 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1312 pWifiRadioStat->rxTime) ||
1313 nla_put_u32(vendor_event,
1314 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1315 pWifiRadioStat->onTimeScan) ||
1316 nla_put_u32(vendor_event,
1317 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1318 pWifiRadioStat->onTimeNbd) ||
1319 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1321 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1324 pWifiRadioStat->onTimeRoamScan) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1327 pWifiRadioStat->onTimePnoScan) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1330 pWifiRadioStat->onTimeHs20) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1333 pWifiRadioStat->numChannels))
1334 {
1335 hddLog(VOS_TRACE_LEVEL_ERROR,
1336 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1337 kfree_skb(vendor_event);
1338 return ;
1339 }
1340
1341 chList = nla_nest_start(vendor_event,
1342 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1343 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1344 {
1345 struct nlattr *chInfo;
1346
1347 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1348 pWifiRadioStat->channels +
1349 (i * sizeof(tSirWifiChannelStats)));
1350
1351 hddLog(VOS_TRACE_LEVEL_INFO,
1352 " %d) Channel Info"
1353 " width is %u "
1354 " CenterFreq %u "
1355 " CenterFreq0 %u "
1356 " CenterFreq1 %u "
1357 " onTime %u "
1358 " ccaBusyTime %u",
1359 i,
1360 pWifiChannelStats->channel.width,
1361 pWifiChannelStats->channel.centerFreq,
1362 pWifiChannelStats->channel.centerFreq0,
1363 pWifiChannelStats->channel.centerFreq1,
1364 pWifiChannelStats->onTime,
1365 pWifiChannelStats->ccaBusyTime);
1366
1367
1368 chInfo = nla_nest_start(vendor_event, i);
1369
1370 if (nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1372 pWifiChannelStats->channel.width) ||
1373 nla_put_u32(vendor_event,
1374 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1375 pWifiChannelStats->channel.centerFreq) ||
1376 nla_put_u32(vendor_event,
1377 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1378 pWifiChannelStats->channel.centerFreq0) ||
1379 nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1381 pWifiChannelStats->channel.centerFreq1) ||
1382 nla_put_u32(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1384 pWifiChannelStats->onTime) ||
1385 nla_put_u32(vendor_event,
1386 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1387 pWifiChannelStats->ccaBusyTime))
1388 {
1389 hddLog(VOS_TRACE_LEVEL_ERROR,
1390 FL("cfg80211_vendor_event_alloc failed") );
1391 kfree_skb(vendor_event);
1392 return ;
1393 }
1394 nla_nest_end(vendor_event, chInfo);
1395 }
1396 nla_nest_end(vendor_event, chList);
1397
1398 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1399 return;
1400}
1401
1402/*
1403 * hdd_link_layer_stats_ind_callback () - This function is called after
1404 * receiving Link Layer indications from FW.This callback converts the firmware
1405 * data to the NL data and send the same to the kernel/upper layers.
1406 */
1407static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1408 int indType,
1409 void *pRsp )
1410{
1411 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCtx;
1412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1413 int status;
1414
1415 status = wlan_hdd_validate_context(pHddCtx);
1416
1417 if (0 != status)
1418 {
1419 hddLog(VOS_TRACE_LEVEL_ERROR,
1420 FL("HDD context is not valid"));
1421 return;
1422 }
1423
1424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1425 "%s: Link Layer Indication indType: %d", __func__, indType);
1426 switch (indType)
1427 {
1428 case SIR_HAL_LL_STATS_RESULTS_RSP:
1429 {
1430 tpSirLLStatsResults linkLayerStatsResults =
1431 (tpSirLLStatsResults)pRsp;
1432
1433
1434 hddLog(VOS_TRACE_LEVEL_INFO,
1435 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1436 hddLog(VOS_TRACE_LEVEL_INFO,
1437 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1438 linkLayerStatsResults->paramId);
1439 hddLog(VOS_TRACE_LEVEL_INFO,
1440 "LL_STATS RESULTS RESPONSE ifaceId = %u",
1441 linkLayerStatsResults->ifaceId);
1442 hddLog(VOS_TRACE_LEVEL_INFO,
1443 "LL_STATS RESULTS RESPONSE respId = %u",
1444 linkLayerStatsResults->respId);
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1447 linkLayerStatsResults->moreResultToFollow);
1448 hddLog(VOS_TRACE_LEVEL_INFO,
1449 "LL_STATS RESULTS RESPONSE result = %p",
1450 linkLayerStatsResults->result);
1451 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1452 {
1453 hdd_link_layer_process_radio_stats(pAdapter,
1454 (v_VOID_t *)linkLayerStatsResults->result);
1455 }
1456 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1457 {
1458 hdd_link_layer_process_iface_stats(pAdapter,
1459 (v_VOID_t *)linkLayerStatsResults->result);
1460 }
1461 else if ( linkLayerStatsResults->paramId &
1462 WMI_LINK_STATS_ALL_PEER )
1463 {
1464 hdd_link_layer_process_peer_stats(pAdapter,
1465 (v_VOID_t *)linkLayerStatsResults->result);
1466 } /* WMI_LINK_STATS_ALL_PEER */
1467 else
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
1470 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1471 }
1472
1473 break;
1474 }
1475 default:
1476 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1477 break;
1478 }
1479 return;
1480}
1481
1482const struct
1483nla_policy
1484qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1485{
1486 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1487 { .type = NLA_U32 },
1488 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1489 { .type = NLA_U32 },
1490};
1491
1492static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1493 struct wireless_dev *wdev,
1494 void *data,
1495 int data_len)
1496{
1497 int status;
1498 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
1499 tpSirLLStatsSetReq pLinkLayerStatsSetReq;
1500 struct net_device *dev = wdev->netdev;
1501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1503
1504 status = wlan_hdd_validate_context(pHddCtx);
1505 if (0 != status)
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 FL("HDD context is not valid"));
1509 return -EINVAL;
1510 }
1511
1512 if (NULL == pAdapter)
1513 {
1514 hddLog(VOS_TRACE_LEVEL_ERROR,
1515 FL("HDD adapter is Null"));
1516 return -ENODEV;
1517 }
1518
1519 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1520 (struct nlattr *)data,
1521 data_len, qca_wlan_vendor_ll_set_policy))
1522 {
1523 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1524 return -EINVAL;
1525 }
1526 if (!tb_vendor
1527 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1528 {
1529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1530 return -EINVAL;
1531 }
1532 if (!tb_vendor[
1533 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1536 return -EINVAL;
1537 }
1538 pLinkLayerStatsSetReq = vos_mem_malloc(sizeof(tSirLLStatsSetReq));
1539 if (NULL == pLinkLayerStatsSetReq)
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 FL(" Unable to allocate memory to pLinkLayerStatsSetReq") );
1543 return -ENOMEM;
1544 }
1545 // Shall take the request Id if the Upper layers pass. 1 For now.
1546 pLinkLayerStatsSetReq->reqId = 1;
1547
1548 pLinkLayerStatsSetReq->mpduSizeThreshold =
1549 nla_get_u32(
1550 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1551
1552 pLinkLayerStatsSetReq->aggressiveStatisticsGathering =
1553 nla_get_u32(
1554 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1555
1556 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1557 * Hence the interface staId start from 1. Hence the staId matching the
1558 * interface in the firmware is sessionId + 1.
1559 */
1560 pLinkLayerStatsSetReq->staId = pAdapter->sessionId + 1;
1561
1562
1563 hddLog(VOS_TRACE_LEVEL_INFO,
1564 "LL_STATS_SET reqId = %d",
1565 pLinkLayerStatsSetReq->reqId);
1566 hddLog(VOS_TRACE_LEVEL_INFO,
1567 "LL_STATS_SET staId = %d", pLinkLayerStatsSetReq->staId);
1568 hddLog(VOS_TRACE_LEVEL_INFO,
1569 "LL_STATS_SET mpduSizeThreshold = %d",
1570 pLinkLayerStatsSetReq->mpduSizeThreshold);
1571 hddLog(VOS_TRACE_LEVEL_INFO,
1572 "LL_STATS_SET aggressive Statistics Gathering = %d",
1573 pLinkLayerStatsSetReq->aggressiveStatisticsGathering);
1574
1575 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1576 pHddCtx->hHal,
1577 pAdapter->sessionId,
1578 hdd_link_layer_stats_ind_callback,
1579 pAdapter))
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1582 "sme_SetLinkLayerStatsIndCB Failed", __func__);
1583 vos_mem_free(pLinkLayerStatsSetReq);
1584 return -EINVAL;
1585
1586 }
1587 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
1588 pLinkLayerStatsSetReq))
1589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1591 "sme_LLStatsSetReq Failed", __func__);
1592 vos_mem_free(pLinkLayerStatsSetReq);
1593 return -EINVAL;
1594 }
1595
1596 pAdapter->isLinkLayerStatsSet = 1;
1597
1598 return 0;
1599}
1600
1601const struct
1602nla_policy
1603qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1604{
1605 /* Unsigned 32bit value provided by the caller issuing the GET stats
1606 * command. When reporting
1607 * the stats results, the driver uses the same value to indicate
1608 * which GET request the results
1609 * correspond to.
1610 */
1611 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1612
1613 /* Unsigned 32bit value . bit mask to identify what statistics are
1614 requested for retrieval */
1615 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1616};
1617
1618static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1619 struct wireless_dev *wdev,
1620 void *data,
1621 int data_len)
1622{
1623 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1624 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
1625 tpSirLLStatsGetReq pLinkLayerStatsGetReq;
1626 struct net_device *dev = wdev->netdev;
1627 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1628 int status;
1629
1630 status = wlan_hdd_validate_context(pHddCtx);
1631 if (0 != status)
1632 {
1633 hddLog(VOS_TRACE_LEVEL_ERROR,
1634 FL("HDD context is not valid"));
1635 return -EINVAL ;
1636 }
1637
1638 if (NULL == pAdapter)
1639 {
1640 hddLog(VOS_TRACE_LEVEL_FATAL,
1641 "%s: HDD adapter is Null", __func__);
1642 return -ENODEV;
1643 }
1644
1645 if (!pAdapter->isLinkLayerStatsSet)
1646 {
1647 hddLog(VOS_TRACE_LEVEL_FATAL,
1648 "%s: isLinkLayerStatsSet : %d",
1649 __func__, pAdapter->isLinkLayerStatsSet);
1650 return -EINVAL;
1651 }
1652
1653 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1654 (struct nlattr *)data,
1655 data_len, qca_wlan_vendor_ll_get_policy))
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1658 return -EINVAL;
1659 }
1660
1661 if (!tb_vendor
1662 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1663 {
1664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1665 return -EINVAL;
1666 }
1667
1668 if (!tb_vendor
1669 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1670 {
1671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1672 return -EINVAL;
1673 }
1674
1675 pLinkLayerStatsGetReq = vos_mem_malloc(sizeof(tSirLLStatsGetReq));
1676
1677 if (NULL == pLinkLayerStatsGetReq)
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("Unable to allocate memory to pLinkLayerStatsGetReq"));
1681 return -ENOMEM;
1682 }
1683
1684 pLinkLayerStatsGetReq->reqId =
1685 nla_get_u32( tb_vendor[
1686 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
1687 pLinkLayerStatsGetReq->paramIdMask =
1688 nla_get_u32( tb_vendor[
1689 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1690
1691 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1692 * Hence the interface staId start from 1. Hence the staId matching the
1693 * interface in the firmware is sessionId + 1.
1694 */
1695 pLinkLayerStatsGetReq->staId = pAdapter->sessionId + 1;
1696
1697 hddLog(VOS_TRACE_LEVEL_INFO,
1698 "LL_STATS_GET reqId = %d", pLinkLayerStatsGetReq->reqId);
1699 hddLog(VOS_TRACE_LEVEL_INFO,
1700 "LL_STATS_GET staId = %d", pLinkLayerStatsGetReq->staId);
1701 hddLog(VOS_TRACE_LEVEL_INFO,
1702 "LL_STATS_GET paramIdMask = %d",
1703 pLinkLayerStatsGetReq->paramIdMask);
1704
1705 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
1706 pLinkLayerStatsGetReq))
1707 {
1708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1709 "sme_LLStatsGetReq Failed", __func__);
1710 vos_mem_free(pLinkLayerStatsGetReq);
1711 return -EINVAL;
1712 }
1713 return 0;
1714}
1715
1716const struct
1717nla_policy
1718qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1719{
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1721 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1724};
1725
1726static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1727 struct wireless_dev *wdev,
1728 void *data,
1729 int data_len)
1730{
1731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1732 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
1733 tpSirLLStatsClearReq pLinkLayerStatsClearReq;
1734 struct net_device *dev = wdev->netdev;
1735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1736 u32 statsClearReqMask;
1737 u8 stopReq;
1738 int status;
1739
1740 status = wlan_hdd_validate_context(pHddCtx);
1741 if (0 != status)
1742 {
1743 hddLog(VOS_TRACE_LEVEL_ERROR,
1744 FL("HDD context is not valid"));
1745 return -EINVAL;
1746 }
1747
1748 if (NULL == pAdapter)
1749 {
1750 hddLog(VOS_TRACE_LEVEL_FATAL,
1751 "%s: HDD adapter is Null", __func__);
1752 return -ENODEV;
1753 }
1754
1755 if (!pAdapter->isLinkLayerStatsSet)
1756 {
1757 hddLog(VOS_TRACE_LEVEL_FATAL,
1758 "%s: isLinkLayerStatsSet : %d",
1759 __func__, pAdapter->isLinkLayerStatsSet);
1760 return -EINVAL;
1761 }
1762
1763 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1764 (struct nlattr *)data,
1765 data_len, qca_wlan_vendor_ll_clr_policy))
1766 {
1767 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1768 return -EINVAL;
1769 }
1770
1771 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1772
1773 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1774 {
1775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1776 return -EINVAL;
1777
1778 }
1779
1780 pLinkLayerStatsClearReq = vos_mem_malloc(sizeof(tSirLLStatsClearReq));
1781 if (NULL == pLinkLayerStatsClearReq)
1782 {
1783 hddLog(VOS_TRACE_LEVEL_ERROR,
1784 FL("Unable to allocate memory to pLinkLayerStatsClearReq"));
1785 return -ENOMEM;
1786 }
1787
1788 statsClearReqMask = pLinkLayerStatsClearReq->statsClearReqMask =
1789 nla_get_u32(
1790 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1791
1792 stopReq = pLinkLayerStatsClearReq->stopReq =
1793 nla_get_u8(
1794 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1795
1796 // Shall take the request Id if the Upper layers pass. 1 For now.
1797 pLinkLayerStatsClearReq->reqId = 1;
1798
1799 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1800 * Hence the interface staId start from 1. Hence the staId matching the
1801 * interface in the firmware is sessionId + 1.
1802 */
1803 pLinkLayerStatsClearReq->staId = pAdapter->sessionId + 1;
1804
1805 hddLog(VOS_TRACE_LEVEL_INFO,
1806 "LL_STATS_CLEAR reqId = %d", pLinkLayerStatsClearReq->reqId);
1807 hddLog(VOS_TRACE_LEVEL_INFO,
1808 "LL_STATS_CLEAR staId = %d", pLinkLayerStatsClearReq->staId);
1809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
1811 pLinkLayerStatsClearReq->statsClearReqMask);
1812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_CLEAR stopReq = %d",
1814 pLinkLayerStatsClearReq->stopReq);
1815
1816 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
1817 pLinkLayerStatsClearReq))
1818 {
1819 struct sk_buff *temp_skbuff;
1820 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1821 2 * sizeof(u32) +
1822 NLMSG_HDRLEN);
1823
1824 if (temp_skbuff != NULL)
1825 {
1826
1827 if (nla_put_u32(temp_skbuff,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1829 statsClearReqMask) ||
1830 nla_put_u32(temp_skbuff,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1832 stopReq))
1833 {
1834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1835 kfree_skb(temp_skbuff);
1836 return -EINVAL;
1837 }
1838 /* If the ask is to stop the stats collection as part of clear
1839 * (stopReq = 1) , ensure that no further requests of get
1840 * go to the firmware by having isLinkLayerStatsSet set to 0.
1841 * However it the stopReq as part of the clear request is 0 ,
1842 * the request to get the statistics are ehonoured as in this
1843 * case the firmware is just asked to clear the statistics.
1844 */
1845 if (pLinkLayerStatsClearReq->stopReq == 1)
1846 pAdapter->isLinkLayerStatsSet = 0;
1847 return cfg80211_vendor_cmd_reply(temp_skbuff);
1848 }
1849 return -ENOMEM;
1850 }
1851 vos_mem_free(pLinkLayerStatsClearReq);
1852 return -EINVAL;
1853}
1854#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1855
Dino Mycle6fb96c12014-06-10 11:52:40 +05301856#ifdef WLAN_FEATURE_EXTSCAN
1857static const struct nla_policy
1858wlan_hdd_extscan_config_policy
1859 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1860{
1861 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1862 { .type = NLA_U32 },
1863 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1864 { .type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1866 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1867 { .type = NLA_U32 },
1868 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1869 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1870
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1873 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1874 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1875 { .type = NLA_U8 },
1876 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1877 { .type = NLA_U32 },
1878 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1879 { .type = NLA_U32 },
1880 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1881 { .type = NLA_U32 },
1882 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1883 { .type = NLA_U8 },
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1885 { .type = NLA_U8 },
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1887 { .type = NLA_U8 },
1888
1889 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1890 { .type = NLA_U32 },
1891 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1892 { .type = NLA_UNSPEC },
1893 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1894 { .type = NLA_S32 },
1895 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1896 { .type = NLA_S32 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1898 { .type = NLA_U32 },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1900 { .type = NLA_U32 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1902 { .type = NLA_U32 },
1903 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1904 = { .type = NLA_U32 },
1905 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1906 { .type = NLA_U32 },
1907 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1908 NLA_U32 },
1909};
1910
1911static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1912{
1913 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1914 struct sk_buff *skb = NULL;
1915 tpSirEXTScanCapabilitiesEvent pData =
1916 (tpSirEXTScanCapabilitiesEvent) pMsg;
1917
1918 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1920 "or pData(%p) is null"), pData);
1921 return;
1922 }
1923
1924 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1925 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1926 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1927 GFP_KERNEL);
1928
1929 if (!skb) {
1930 hddLog(VOS_TRACE_LEVEL_ERROR,
1931 FL("cfg80211_vendor_event_alloc failed"));
1932 return;
1933 }
1934
1935 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1936 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1937 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1938 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1939 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1940 pData->maxRssiSampleSize);
1941 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1942 pData->maxScanReportingThreshold);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1944 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1945 pData->maxSignificantWifiChangeAPs);
1946 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1947 pData->maxBsidHistoryEntries);
1948
1949 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1950 pData->requestId) ||
1951 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1952 nla_put_u32(skb,
1953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1954 pData->scanCacheSize) ||
1955 nla_put_u32(skb,
1956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1957 pData->scanBuckets) ||
1958 nla_put_u32(skb,
1959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1960 pData->maxApPerScan) ||
1961 nla_put_u32(skb,
1962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1963 pData->maxRssiSampleSize) ||
1964 nla_put_u32(skb,
1965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1966 pData->maxScanReportingThreshold) ||
1967 nla_put_u32(skb,
1968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1969 pData->maxHotlistAPs) ||
1970 nla_put_u32(skb,
1971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1972 pData->maxSignificantWifiChangeAPs) ||
1973 nla_put_u32(skb,
1974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1975 pData->maxBsidHistoryEntries)) {
1976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1977 goto nla_put_failure;
1978 }
1979
1980 cfg80211_vendor_event(skb, GFP_KERNEL);
1981 return;
1982
1983nla_put_failure:
1984 kfree_skb(skb);
1985 return;
1986}
1987
1988
1989static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1990{
1991 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1992 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1993 struct sk_buff *skb = NULL;
1994 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
1995
1996
1997 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1999 "or pData(%p) is null"), pData);
2000 return;
2001 }
2002
2003 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2004 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2005 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2006 GFP_KERNEL);
2007
2008 if (!skb) {
2009 hddLog(VOS_TRACE_LEVEL_ERROR,
2010 FL("cfg80211_vendor_event_alloc failed"));
2011 return;
2012 }
2013 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2014 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2015 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2016
2017 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2018 pData->requestId) ||
2019 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2021 goto nla_put_failure;
2022 }
2023
2024 /*
2025 * Store the Request ID for comparing with the requestID obtained
2026 * in other requests.HDD shall return a failure is the extscan_stop
2027 * request is issued with a different requestId as that of the
2028 * extscan_start request. Also, This requestId shall be used while
2029 * indicating the full scan results to the upper layers.
2030 * The requestId is stored with the assumption that the firmware
2031 * shall return the ext scan start request's requestId in ext scan
2032 * start response.
2033 */
2034 if (pData->status == 0)
2035 pMac->sme.extScanStartReqId = pData->requestId;
2036
2037
2038 cfg80211_vendor_event(skb, GFP_KERNEL);
2039 return;
2040
2041nla_put_failure:
2042 kfree_skb(skb);
2043 return;
2044}
2045
2046
2047static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2048{
2049 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2050 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2051 struct sk_buff *skb = NULL;
2052
2053 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2055 "or pData(%p) is null"), pData);
2056 return;
2057 }
2058
2059 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2060 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2061 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2062 GFP_KERNEL);
2063
2064 if (!skb) {
2065 hddLog(VOS_TRACE_LEVEL_ERROR,
2066 FL("cfg80211_vendor_event_alloc failed"));
2067 return;
2068 }
2069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2070 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2071
2072 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2073 pData->requestId) ||
2074 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2076 goto nla_put_failure;
2077 }
2078
2079 cfg80211_vendor_event(skb, GFP_KERNEL);
2080 return;
2081
2082nla_put_failure:
2083 kfree_skb(skb);
2084 return;
2085}
2086
2087
2088static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2089 void *pMsg)
2090{
2091 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2092 struct sk_buff *skb = NULL;
2093 tpSirEXTScanSetBssidHotListRspParams pData =
2094 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2095
2096 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2098 "or pData(%p) is null"), pData);
2099 return;
2100 }
2101 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2102 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2103 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2104 GFP_KERNEL);
2105
2106 if (!skb) {
2107 hddLog(VOS_TRACE_LEVEL_ERROR,
2108 FL("cfg80211_vendor_event_alloc failed"));
2109 return;
2110 }
2111 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2112 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2113 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2114
2115 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2116 pData->requestId) ||
2117 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2119 goto nla_put_failure;
2120 }
2121
2122 cfg80211_vendor_event(skb, GFP_KERNEL);
2123 return;
2124
2125nla_put_failure:
2126 kfree_skb(skb);
2127 return;
2128}
2129
2130static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2131 void *pMsg)
2132{
2133 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2134 struct sk_buff *skb = NULL;
2135 tpSirEXTScanResetBssidHotlistRspParams pData =
2136 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2137
2138 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2140 "or pData(%p) is null"), pData);
2141 return;
2142 }
2143
2144 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2145 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2146 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2147 GFP_KERNEL);
2148
2149 if (!skb) {
2150 hddLog(VOS_TRACE_LEVEL_ERROR,
2151 FL("cfg80211_vendor_event_alloc failed"));
2152 return;
2153 }
2154 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2155 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2156
2157 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2158 pData->requestId) ||
2159 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2161 goto nla_put_failure;
2162 }
2163
2164 cfg80211_vendor_event(skb, GFP_KERNEL);
2165 return;
2166
2167nla_put_failure:
2168 kfree_skb(skb);
2169 return;
2170}
2171
2172
2173static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2174 void *pMsg)
2175{
2176 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2177 struct sk_buff *skb = NULL;
2178 tpSirEXTScanSetSignificantChangeRspParams pData =
2179 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2180
2181 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2183 "or pData(%p) is null"), pData);
2184 return;
2185 }
2186
2187 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2188 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2189 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2190 GFP_KERNEL);
2191
2192 if (!skb) {
2193 hddLog(VOS_TRACE_LEVEL_ERROR,
2194 FL("cfg80211_vendor_event_alloc failed"));
2195 return;
2196 }
2197 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2198 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2199 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2200
2201 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2202 pData->requestId) ||
2203 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2205 goto nla_put_failure;
2206 }
2207
2208 cfg80211_vendor_event(skb, GFP_KERNEL);
2209 return;
2210
2211nla_put_failure:
2212 kfree_skb(skb);
2213 return;
2214}
2215
2216
2217static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2218 void *pMsg)
2219{
2220 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2221 struct sk_buff *skb = NULL;
2222 tpSirEXTScanResetSignificantChangeRspParams pData =
2223 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2224
2225 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2227 "or pData(%p) is null"), pData);
2228 return;
2229 }
2230
2231 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2232 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2233 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2234 GFP_KERNEL);
2235
2236 if (!skb) {
2237 hddLog(VOS_TRACE_LEVEL_ERROR,
2238 FL("cfg80211_vendor_event_alloc failed"));
2239 return;
2240 }
2241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2242 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2243 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2244
2245 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2246 pData->requestId) ||
2247 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2249 goto nla_put_failure;
2250 }
2251
2252 cfg80211_vendor_event(skb, GFP_KERNEL);
2253 return;
2254
2255nla_put_failure:
2256 kfree_skb(skb);
2257 return;
2258}
2259
2260static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2261 void *pMsg)
2262{
2263 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2264 struct sk_buff *skb = NULL;
2265 tANI_U32 i = 0, j, resultsPerEvent;
2266 tANI_S32 totalResults;
2267 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2268 tpSirWifiScanResult pSirWifiScanResult;
2269
2270 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2272 "or pData(%p) is null"), pData);
2273 return;
2274 }
2275 totalResults = pData->numOfAps;
2276 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2277 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2278 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2279
2280 do{
2281 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2282 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2283 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2284
2285 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2286 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2287 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2288 GFP_KERNEL);
2289
2290 if (!skb) {
2291 hddLog(VOS_TRACE_LEVEL_ERROR,
2292 FL("cfg80211_vendor_event_alloc failed"));
2293 return;
2294 }
2295
2296 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2297
2298 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2299 pData->requestId) ||
2300 nla_put_u32(skb,
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2302 resultsPerEvent)) {
2303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2304 goto fail;
2305 }
2306 if (nla_put_u8(skb,
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2308 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2309 {
2310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2311 goto fail;
2312 }
2313
2314 if (resultsPerEvent) {
2315 struct nlattr *aps;
2316
2317 aps = nla_nest_start(skb,
2318 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2319 if (!aps)
2320 {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2322 goto fail;
2323 }
2324
2325 for (j = 0; j < resultsPerEvent; j++, i++) {
2326 struct nlattr *ap;
2327 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2328 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2329
2330 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2331 "Ssid (%s)"
2332 "Bssid: %pM "
2333 "Channel (%u)"
2334 "Rssi (%d)"
2335 "RTT (%u)"
2336 "RTT_SD (%u)",
2337 i,
2338 pSirWifiScanResult->ts,
2339 pSirWifiScanResult->ssid,
2340 pSirWifiScanResult->bssid,
2341 pSirWifiScanResult->channel,
2342 pSirWifiScanResult->rssi,
2343 pSirWifiScanResult->rtt,
2344 pSirWifiScanResult->rtt_sd);
2345
2346 ap = nla_nest_start(skb, j + 1);
2347 if (!ap)
2348 {
2349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2350 goto fail;
2351 }
2352
2353 if (nla_put_u64(skb,
2354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2355 pSirWifiScanResult->ts) )
2356 {
2357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2358 goto fail;
2359 }
2360 if (nla_put(skb,
2361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2362 sizeof(pSirWifiScanResult->ssid),
2363 pSirWifiScanResult->ssid) )
2364 {
2365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2366 goto fail;
2367 }
2368 if (nla_put(skb,
2369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2370 sizeof(pSirWifiScanResult->bssid),
2371 pSirWifiScanResult->bssid) )
2372 {
2373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2374 goto fail;
2375 }
2376 if (nla_put_u32(skb,
2377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2378 pSirWifiScanResult->channel) )
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2381 goto fail;
2382 }
2383 if (nla_put_u32(skb,
2384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2385 pSirWifiScanResult->rssi) )
2386 {
2387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2388 goto fail;
2389 }
2390 if (nla_put_u32(skb,
2391 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2392 pSirWifiScanResult->rtt) )
2393 {
2394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2395 goto fail;
2396 }
2397 if (nla_put_u32(skb,
2398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2399 pSirWifiScanResult->rtt_sd))
2400 {
2401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2402 goto fail;
2403 }
2404
2405 nla_nest_end(skb, ap);
2406 }
2407 nla_nest_end(skb, aps);
2408
2409 }
2410 cfg80211_vendor_event(skb, GFP_KERNEL);
2411 } while (totalResults > 0);
2412
2413 return;
2414fail:
2415 kfree_skb(skb);
2416 return;
2417}
2418
2419static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2420 void *pMsg)
2421{
2422 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tANI_U32 i;
2426
2427 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2429 "or pData(%p) is null"), pData);
2430 return;
2431 }
2432
2433 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2434 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2435 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2436 GFP_KERNEL);
2437
2438 if (!skb) {
2439 hddLog(VOS_TRACE_LEVEL_ERROR,
2440 FL("cfg80211_vendor_event_alloc failed"));
2441 return;
2442 }
2443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2445 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2446 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2447
2448 for (i = 0; i < pData->numOfAps; i++) {
2449 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2450 "Ssid (%s) "
2451 "Bssid (" MAC_ADDRESS_STR ") "
2452 "Channel (%u) "
2453 "Rssi (%d) "
2454 "RTT (%u) "
2455 "RTT_SD (%u) ",
2456 i,
2457 pData->ap[i].ts,
2458 pData->ap[i].ssid,
2459 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2460 pData->ap[i].channel,
2461 pData->ap[i].rssi,
2462 pData->ap[i].rtt,
2463 pData->ap[i].rtt_sd);
2464 }
2465
2466 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2467 pData->requestId) ||
2468 nla_put_u32(skb,
2469 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2470 pData->numOfAps)) {
2471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2472 goto fail;
2473 }
2474 if (pData->numOfAps) {
2475 struct nlattr *aps;
2476
2477 aps = nla_nest_start(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2479 if (!aps)
2480 goto fail;
2481
2482 for (i = 0; i < pData->numOfAps; i++) {
2483 struct nlattr *ap;
2484
2485 ap = nla_nest_start(skb, i + 1);
2486 if (!ap)
2487 goto fail;
2488
2489 if (nla_put_u64(skb,
2490 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2491 pData->ap[i].ts) ||
2492 nla_put(skb,
2493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2494 sizeof(pData->ap[i].ssid),
2495 pData->ap[i].ssid) ||
2496 nla_put(skb,
2497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2498 sizeof(pData->ap[i].bssid),
2499 pData->ap[i].bssid) ||
2500 nla_put_u32(skb,
2501 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2502 pData->ap[i].channel) ||
2503 nla_put_s32(skb,
2504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2505 pData->ap[i].rssi) ||
2506 nla_put_u32(skb,
2507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2508 pData->ap[i].rtt) ||
2509 nla_put_u32(skb,
2510 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2511 pData->ap[i].rtt_sd))
2512 goto fail;
2513
2514 nla_nest_end(skb, ap);
2515 }
2516 nla_nest_end(skb, aps);
2517
2518 if (nla_put_u8(skb,
2519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2520 pData->moreData))
2521 goto fail;
2522 }
2523
2524 cfg80211_vendor_event(skb, GFP_KERNEL);
2525 return;
2526
2527fail:
2528 kfree_skb(skb);
2529 return;
2530
2531}
2532static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2533 void *pMsg)
2534{
2535 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2536 struct sk_buff *skb = NULL;
2537 tANI_U32 i, j;
2538 tpSirWifiSignificantChangeEvent pData =
2539 (tpSirWifiSignificantChangeEvent) pMsg;
2540
2541 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2543 "or pData(%p) is null"), pData);
2544 return;
2545 }
2546 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2547 EXTSCAN_EVENT_BUF_SIZE,
2548 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2549 GFP_KERNEL);
2550
2551 if (!skb) {
2552 hddLog(VOS_TRACE_LEVEL_ERROR,
2553 FL("cfg80211_vendor_event_alloc failed"));
2554 return;
2555 }
2556 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2557 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2558 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2559 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2560 pData->numSigRssiBss);
2561 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2562
2563 for (i = 0; i < pData->numSigRssiBss; i++) {
2564 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2565 " num RSSI %u ",
2566 i, pData->sigRssiResult[i].bssid,
2567 pData->sigRssiResult[i].channel,
2568 pData->sigRssiResult[i].numRssi);
2569
2570 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2571
2572 hddLog(VOS_TRACE_LEVEL_INFO,
2573 " [%d]",
2574 pData->sigRssiResult[i].rssi[0]);
2575
2576 }
2577 }
2578
2579
2580 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2581 pData->requestId) ||
2582 nla_put_u32(skb,
2583 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2584 pData->numSigRssiBss)) {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2586 goto fail;
2587 }
2588
2589 if (pData->numSigRssiBss) {
2590 struct nlattr *aps;
2591 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2592 if (!aps)
2593 goto fail;
2594 for (i = 0; i < pData->numSigRssiBss; i++) {
2595 struct nlattr *ap;
2596
2597 ap = nla_nest_start(skb, i);
2598 if (!ap)
2599 goto fail;
2600 if (nla_put(skb,
2601 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2602 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2603 nla_put_u32(skb,
2604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2605 pData->sigRssiResult[i].channel) ||
2606 nla_put_u32(skb,
2607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2608 pData->sigRssiResult[i].numRssi) ||
2609 nla_put(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2611 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2612 pData->sigRssiResult[i].rssi))
2613 goto fail;
2614 nla_nest_end(skb, ap);
2615 }
2616 nla_nest_end(skb, aps);
2617 if (nla_put_u8(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2619 pData->moreData))
2620 goto fail;
2621 }
2622 cfg80211_vendor_event(skb, GFP_KERNEL);
2623 return;
2624fail:
2625 kfree_skb(skb);
2626 return;
2627}
2628
2629static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2630 void *pMsg)
2631{
2632 struct sk_buff *skb;
2633 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2634 tpSirWifiFullScanResultEvent pData =
2635 (tpSirWifiFullScanResultEvent) (pMsg);
2636
2637 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2639 "or pData(%p) is null"), pData);
2640 return;
2641 }
2642
2643 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2644 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2645 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2646 GFP_KERNEL);
2647
2648 if (!skb) {
2649 hddLog(VOS_TRACE_LEVEL_ERROR,
2650 FL("cfg80211_vendor_event_alloc failed"));
2651 return;
2652 }
2653
2654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2657 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2658 "Ssid (%s)"
2659 "Bssid (" MAC_ADDRESS_STR ")"
2660 "Channel (%u)"
2661 "Rssi (%d)"
2662 "RTT (%u)"
2663 "RTT_SD (%u)"),
2664 pData->ap.ts,
2665 pData->ap.ssid,
2666 MAC_ADDR_ARRAY(pData->ap.bssid),
2667 pData->ap.channel,
2668 pData->ap.rssi,
2669 pData->ap.rtt,
2670 pData->ap.rtt_sd);
2671 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u64(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2676 pData->ap.ts) ||
2677 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2678 sizeof(pData->ap.ssid),
2679 pData->ap.ssid) ||
2680 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2681 WNI_CFG_BSSID_LEN,
2682 pData->ap.bssid) ||
2683 nla_put_u32(skb,
2684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2685 pData->ap.channel) ||
2686 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2687 pData->ap.rssi) ||
2688 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2689 pData->ap.rtt) ||
2690 nla_put_u32(skb,
2691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2692 pData->ap.rtt_sd) ||
2693 nla_put_u16(skb,
2694 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2695 pData->ap.beaconPeriod) ||
2696 nla_put_u16(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2698 pData->ap.capability) ||
2699 nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2701 pData->ieLength))
2702 {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2704 goto nla_put_failure;
2705 }
2706 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2707 pData->ieLength,
2708 pData->ie))
2709 {
2710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2711 goto nla_put_failure;
2712 }
2713
2714 cfg80211_vendor_event(skb, GFP_KERNEL);
2715 return;
2716
2717nla_put_failure:
2718 kfree_skb(skb);
2719 return;
2720}
2721
2722static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2723 void *pMsg)
2724{
2725 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2726 struct sk_buff *skb = NULL;
2727 tpSirEXTScanResultsAvailableIndParams pData =
2728 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2729
2730 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2732 "or pData(%p) is null"), pData);
2733 return;
2734 }
2735
2736 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2737 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2738 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2739 GFP_KERNEL);
2740
2741 if (!skb) {
2742 hddLog(VOS_TRACE_LEVEL_ERROR,
2743 FL("cfg80211_vendor_event_alloc failed"));
2744 return;
2745 }
2746
2747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2748 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2749 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2750 pData->numResultsAvailable);
2751 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2752 pData->requestId) ||
2753 nla_put_u32(skb,
2754 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2755 pData->numResultsAvailable)) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2757 goto nla_put_failure;
2758 }
2759
2760 cfg80211_vendor_event(skb, GFP_KERNEL);
2761 return;
2762
2763nla_put_failure:
2764 kfree_skb(skb);
2765 return;
2766}
2767
2768static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2769{
2770 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2771 struct sk_buff *skb = NULL;
2772 tpSirEXTScanProgressIndParams pData =
2773 (tpSirEXTScanProgressIndParams) pMsg;
2774
2775 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2777 "or pData(%p) is null"), pData);
2778 return;
2779 }
2780
2781 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2782 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2783 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2784 GFP_KERNEL);
2785
2786 if (!skb) {
2787 hddLog(VOS_TRACE_LEVEL_ERROR,
2788 FL("cfg80211_vendor_event_alloc failed"));
2789 return;
2790 }
2791 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2792 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2793 pData->extScanEventType);
2794 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2795 pData->status);
2796
2797 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2798 pData->extScanEventType) ||
2799 nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2801 pData->status)) {
2802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2803 goto nla_put_failure;
2804 }
2805
2806 cfg80211_vendor_event(skb, GFP_KERNEL);
2807 return;
2808
2809nla_put_failure:
2810 kfree_skb(skb);
2811 return;
2812}
2813
2814void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2815 void *pMsg)
2816{
2817 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2818
2819 if (wlan_hdd_validate_context(pHddCtx)) {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2821 return;
2822 }
2823
2824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2825
2826
2827 switch(evType) {
2828 case SIR_HAL_EXTSCAN_START_RSP:
2829 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2830 break;
2831
2832 case SIR_HAL_EXTSCAN_STOP_RSP:
2833 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2834 break;
2835 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2836 /* There is no need to send this response to upper layer
2837 Just log the message */
2838 hddLog(VOS_TRACE_LEVEL_INFO,
2839 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2840 break;
2841 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2842 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2843 break;
2844
2845 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2846 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2847 break;
2848
2849 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2850 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2851 break;
2852
2853 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2854 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2855 break;
2856 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2857 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2858 break;
2859 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2860 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2861 break;
2862 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2863 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2864 break;
2865 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2866 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2867 break;
2868 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2869 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2870 break;
2871 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2872 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2875 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2876 break;
2877 default:
2878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2879 break;
2880 }
2881}
2882
2883static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2884 struct wireless_dev *wdev,
2885 void *data, int dataLen)
2886{
2887 tpSirGetEXTScanCapabilitiesReqParams pReqMsg = NULL;
2888 struct net_device *dev = wdev->netdev;
2889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2890 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2891 struct nlattr
2892 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2893 eHalStatus status;
2894
2895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2896 status = wlan_hdd_validate_context(pHddCtx);
2897 if (0 != status)
2898 {
2899 hddLog(VOS_TRACE_LEVEL_ERROR,
2900 FL("HDD context is not valid"));
2901 return -EINVAL;
2902 }
2903 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2904 data, dataLen,
2905 wlan_hdd_extscan_config_policy)) {
2906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2907 return -EINVAL;
2908 }
2909
2910 /* Parse and fetch request Id */
2911 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2913 return -EINVAL;
2914 }
2915
2916 pReqMsg = (tpSirGetEXTScanCapabilitiesReqParams)
2917 vos_mem_malloc(sizeof(*pReqMsg));
2918 if (!pReqMsg) {
2919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2920 return -ENOMEM;
2921 }
2922
2923 pReqMsg->requestId = nla_get_u32(
2924 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2925 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2926
2927 pReqMsg->sessionId = pAdapter->sessionId;
2928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2929
2930 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, pReqMsg);
2931 if (!HAL_STATUS_SUCCESS(status)) {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
2934 vos_mem_free(pReqMsg);
2935 return -EINVAL;
2936 }
2937
2938 return 0;
2939}
2940
2941
2942static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2943 struct wireless_dev *wdev,
2944 void *data, int dataLen)
2945{
2946 tpSirEXTScanGetCachedResultsReqParams pReqMsg = NULL;
2947 struct net_device *dev = wdev->netdev;
2948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2950 struct nlattr
2951 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2952 eHalStatus status;
2953
2954 status = wlan_hdd_validate_context(pHddCtx);
2955 if (0 != status)
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR,
2958 FL("HDD context is not valid"));
2959 return -EINVAL;
2960 }
2961 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2962 data, dataLen,
2963 wlan_hdd_extscan_config_policy)) {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2965 return -EINVAL;
2966 }
2967 /* Parse and fetch request Id */
2968 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2970 return -EINVAL;
2971 }
2972 pReqMsg = (tpSirEXTScanGetCachedResultsReqParams)
2973 vos_mem_malloc(sizeof(*pReqMsg));
2974 if (!pReqMsg) {
2975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2976 return -ENOMEM;
2977 }
2978
2979 pReqMsg->requestId = nla_get_u32(
2980 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2981
2982 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2983
2984 pReqMsg->sessionId = pAdapter->sessionId;
2985 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2986
2987 /* Parse and fetch flush parameter */
2988 if (!tb
2989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2990 {
2991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2992 goto failed;
2993 }
2994 pReqMsg->flush = nla_get_u8(
2995 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
2996
2997 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), pReqMsg->flush);
2998
2999 status = sme_getCachedResults(pHddCtx->hHal, pReqMsg);
3000 if (!HAL_STATUS_SUCCESS(status)) {
3001 hddLog(VOS_TRACE_LEVEL_ERROR,
3002 FL("sme_getCachedResults failed(err=%d)"), status);
3003 vos_mem_free(pReqMsg);
3004 return -EINVAL;
3005 }
3006 return 0;
3007
3008failed:
3009 vos_mem_free(pReqMsg);
3010 return -EINVAL;
3011}
3012
3013static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3014 struct wireless_dev *wdev,
3015 void *data, int dataLen)
3016{
3017 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3018 struct net_device *dev = wdev->netdev;
3019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3020 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3021 struct nlattr
3022 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3023 struct nlattr
3024 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3025 struct nlattr *apTh;
3026 eHalStatus status;
3027 tANI_U8 i = 0;
3028 int rem;
3029
3030 status = wlan_hdd_validate_context(pHddCtx);
3031 if (0 != status)
3032 {
3033 hddLog(VOS_TRACE_LEVEL_ERROR,
3034 FL("HDD context is not valid"));
3035 return -EINVAL;
3036 }
3037 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3038 data, dataLen,
3039 wlan_hdd_extscan_config_policy)) {
3040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3041 return -EINVAL;
3042 }
3043
3044 /* Parse and fetch request Id */
3045 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3047 return -EINVAL;
3048 }
3049
3050 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3051 vos_mem_malloc(sizeof(*pReqMsg));
3052 if (!pReqMsg) {
3053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3054 return -ENOMEM;
3055 }
3056
3057 pReqMsg->requestId = nla_get_u32(
3058 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3060
3061 /* Parse and fetch number of APs */
3062 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3064 goto fail;
3065 }
3066
3067 pReqMsg->sessionId = pAdapter->sessionId;
3068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3069
3070 pReqMsg->numAp = nla_get_u32(
3071 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3072 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3073
3074 nla_for_each_nested(apTh,
3075 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3076 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3077 nla_data(apTh), nla_len(apTh),
3078 NULL)) {
3079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3080 goto fail;
3081 }
3082
3083 /* Parse and fetch MAC address */
3084 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3086 goto fail;
3087 }
3088 memcpy(pReqMsg->ap[i].bssid, nla_data(
3089 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3090 sizeof(tSirMacAddr));
3091 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3092
3093 /* Parse and fetch low RSSI */
3094 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3096 goto fail;
3097 }
3098 pReqMsg->ap[i].low = nla_get_s32(
3099 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3100 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3101
3102 /* Parse and fetch high RSSI */
3103 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3105 goto fail;
3106 }
3107 pReqMsg->ap[i].high = nla_get_s32(
3108 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3109 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3110 pReqMsg->ap[i].high);
3111
3112 /* Parse and fetch channel */
3113 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3115 goto fail;
3116 }
3117 pReqMsg->ap[i].channel = nla_get_u32(
3118 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3119 hddLog(VOS_TRACE_LEVEL_INFO,
3120 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3121 i++;
3122 }
3123 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3124 if (!HAL_STATUS_SUCCESS(status)) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR,
3126 FL("sme_SetBssHotlist failed(err=%d)"), status);
3127 vos_mem_free(pReqMsg);
3128 return -EINVAL;
3129 }
3130
3131 return 0;
3132
3133fail:
3134 vos_mem_free(pReqMsg);
3135 return -EINVAL;
3136}
3137
3138static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3139 struct wireless_dev *wdev,
3140 void *data, int dataLen)
3141{
3142 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3143 struct net_device *dev = wdev->netdev;
3144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3145 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3146 struct nlattr
3147 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3148 struct nlattr
3149 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3150 struct nlattr *apTh;
3151 eHalStatus status;
3152 int i = 0;
3153 int rem;
3154
3155 status = wlan_hdd_validate_context(pHddCtx);
3156 if (0 != status)
3157 {
3158 hddLog(VOS_TRACE_LEVEL_ERROR,
3159 FL("HDD context is not valid"));
3160 return -EINVAL;
3161 }
3162 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3163 data, dataLen,
3164 wlan_hdd_extscan_config_policy)) {
3165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3166 return -EINVAL;
3167 }
3168
3169 /* Parse and fetch request Id */
3170 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3172 return -EINVAL;
3173 }
3174
3175 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
3176 vos_mem_malloc(sizeof(*pReqMsg));
3177 if (!pReqMsg) {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3179 return -ENOMEM;
3180 }
3181
3182 pReqMsg->requestId = nla_get_u32(
3183 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3185
3186 /* Parse and fetch RSSI sample size */
3187 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3188 {
3189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3190 goto fail;
3191 }
3192 pReqMsg->rssiSampleSize = nla_get_u32(
3193 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3194 hddLog(VOS_TRACE_LEVEL_INFO,
3195 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3196
3197 /* Parse and fetch lost AP sample size */
3198 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3199 {
3200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3201 goto fail;
3202 }
3203 pReqMsg->lostApSampleSize = nla_get_u32(
3204 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3205 hddLog(VOS_TRACE_LEVEL_INFO,
3206 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3207 /* Parse and fetch minimum Breaching */
3208 if (!tb
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3210 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3211 goto fail;
3212 }
3213 pReqMsg->minBreaching = nla_get_u32(
3214 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3215 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3216
3217 /* Parse and fetch number of APs */
3218 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3220 goto fail;
3221 }
3222 pReqMsg->numAp = nla_get_u32(
3223 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3225
3226 pReqMsg->sessionId = pAdapter->sessionId;
3227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3228
3229 nla_for_each_nested(apTh,
3230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3231 if(nla_parse(tb2,
3232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3233 nla_data(apTh), nla_len(apTh),
3234 NULL)) {
3235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3236 goto fail;
3237 }
3238
3239 /* Parse and fetch MAC address */
3240 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3242 goto fail;
3243 }
3244 memcpy(pReqMsg->ap[i].bssid, nla_data(
3245 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3246 sizeof(tSirMacAddr));
3247
3248 /* Parse and fetch low RSSI */
3249 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3251 goto fail;
3252 }
3253 pReqMsg->ap[i].low = nla_get_s32(
3254 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3255 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3256
3257 /* Parse and fetch high RSSI */
3258 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3260 goto fail;
3261 }
3262 pReqMsg->ap[i].high = nla_get_s32(
3263 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3264 hddLog(VOS_TRACE_LEVEL_INFO,
3265 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3266
3267 /* Parse and fetch channel */
3268 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3270 goto fail;
3271 }
3272 pReqMsg->ap[i].channel = nla_get_u32(
3273 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3274 hddLog(VOS_TRACE_LEVEL_INFO,
3275 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3276 i++;
3277 }
3278
3279 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3280 if (!HAL_STATUS_SUCCESS(status)) {
3281 hddLog(VOS_TRACE_LEVEL_ERROR,
3282 FL("sme_SetSignificantChange failed(err=%d)"), status);
3283 vos_mem_free(pReqMsg);
3284 return -EINVAL;
3285 }
3286
3287 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3288 return 0;
3289
3290fail:
3291 vos_mem_free(pReqMsg);
3292 return -EINVAL;
3293}
3294
3295static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3296 struct wireless_dev *wdev,
3297 void *data, int dataLen)
3298{
3299 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3300 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3301 tANI_U8 numChannels = 0;
3302 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3303 tANI_U32 requestId;
3304 tWifiBand wifiBand;
3305 eHalStatus status;
3306 struct sk_buff *replySkb;
3307 tANI_U8 i;
3308
3309 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3310 status = wlan_hdd_validate_context(pHddCtx);
3311 if (0 != status)
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR,
3314 FL("HDD context is not valid"));
3315 return -EINVAL;
3316 }
3317 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3318 data, dataLen,
3319 wlan_hdd_extscan_config_policy)) {
3320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3321 return -EINVAL;
3322 }
3323
3324 /* Parse and fetch request Id */
3325 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3327 return -EINVAL;
3328 }
3329 requestId = nla_get_u32(
3330 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3332
3333 /* Parse and fetch wifi band */
3334 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3335 {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3337 return -EINVAL;
3338 }
3339 wifiBand = nla_get_u32(
3340 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3342
3343 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3344 wifiBand, ChannelList,
3345 &numChannels);
3346 if (eHAL_STATUS_SUCCESS != status) {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3349 return -EINVAL;
3350 }
3351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3352 for (i = 0; i < numChannels; i++)
3353 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3354
3355 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3356 sizeof(u32) * numChannels +
3357 NLMSG_HDRLEN);
3358
3359 if (!replySkb) {
3360 hddLog(VOS_TRACE_LEVEL_ERROR,
3361 FL("valid channels: buffer alloc fail"));
3362 return -EINVAL;
3363 }
3364 if (nla_put_u32(replySkb,
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3366 numChannels) ||
3367 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3368 sizeof(u32) * numChannels, ChannelList)) {
3369
3370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3371 kfree_skb(replySkb);
3372 return -EINVAL;
3373 }
3374
3375 return cfg80211_vendor_cmd_reply(replySkb);
3376}
3377
3378static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3379 struct wireless_dev *wdev,
3380 void *data, int dataLen)
3381{
3382 tpSirEXTScanStartReqParams pReqMsg = NULL;
3383 struct net_device *dev = wdev->netdev;
3384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3385 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3386 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3387 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3388 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3389 struct nlattr *buckets;
3390 struct nlattr *channels;
3391 int rem1;
3392 int rem2;
3393 eHalStatus status;
3394 tANI_U8 bktIndex;
3395 tANI_U32 i = 0, j = 0;
3396
3397 status = wlan_hdd_validate_context(pHddCtx);
3398 if (0 != status)
3399 {
3400 hddLog(VOS_TRACE_LEVEL_ERROR,
3401 FL("HDD context is not valid"));
3402 return -EINVAL;
3403 }
3404 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3405 data, dataLen,
3406 wlan_hdd_extscan_config_policy)) {
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3408 return -EINVAL;
3409 }
3410
3411 /* Parse and fetch request Id */
3412 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3414 return -EINVAL;
3415 }
3416
3417 pReqMsg = (tpSirEXTScanStartReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3418 if (!pReqMsg) {
3419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3420 return -ENOMEM;
3421 }
3422
3423 pReqMsg->requestId = nla_get_u32(
3424 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3425 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3426
3427 pReqMsg->sessionId = pAdapter->sessionId;
3428 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3429
3430 /* Parse and fetch base period */
3431 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3433 goto fail;
3434 }
3435 pReqMsg->basePeriod = nla_get_u32(
3436 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3437 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3438 pReqMsg->basePeriod);
3439
3440 /* Parse and fetch max AP per scan */
3441 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3443 goto fail;
3444 }
3445 pReqMsg->maxAPperScan = nla_get_u32(
3446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3448 pReqMsg->maxAPperScan);
3449
3450 /* Parse and fetch report threshold */
3451 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3453 goto fail;
3454 }
3455 pReqMsg->reportThreshold = nla_get_u8(
3456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3458 pReqMsg->reportThreshold);
3459
3460 /* Parse and fetch number of buckets */
3461 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3463 goto fail;
3464 }
3465 pReqMsg->numBuckets = nla_get_u8(
3466 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3467 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3468 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3469 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3470 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3471 }
3472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3473 pReqMsg->numBuckets);
3474 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3476 goto fail;
3477 }
3478
3479 nla_for_each_nested(buckets,
3480 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3481 if(nla_parse(bucket,
3482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3483 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3485 goto fail;
3486 }
3487
3488 /* Parse and fetch bucket spec */
3489 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3491 goto fail;
3492 }
3493 bktIndex = nla_get_u8(
3494 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3495 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3496 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3497
3498 /* Parse and fetch wifi band */
3499 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3501 goto fail;
3502 }
3503 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3504 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3506 pReqMsg->buckets[bktIndex].band);
3507
3508 /* Parse and fetch period */
3509 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3511 goto fail;
3512 }
3513 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3514 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3515 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3516 pReqMsg->buckets[bktIndex].period);
3517
3518 /* Parse and fetch report events */
3519 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3521 goto fail;
3522 }
3523 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3524 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3525 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3526 pReqMsg->buckets[bktIndex].reportEvents);
3527
3528 /* Parse and fetch number of channels */
3529 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3531 goto fail;
3532 }
3533 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3534 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3535 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3536 pReqMsg->buckets[bktIndex].numChannels);
3537
3538 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3540 goto fail;
3541 }
3542
3543 j = 0;
3544 nla_for_each_nested(channels,
3545 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3546 if(nla_parse(channel,
3547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3548 nla_data(channels), nla_len(channels),
3549 NULL)) { //wlan_hdd_extscan_config_policy here
3550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3551 goto fail;
3552 }
3553
3554 /* Parse and fetch channel */
3555 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3557 goto fail;
3558 }
3559 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3560 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3561 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3562 pReqMsg->buckets[bktIndex].channels[j].channel);
3563
3564 /* Parse and fetch dwell time */
3565 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3567 goto fail;
3568 }
3569 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3570 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3572 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3573
3574 /* Parse and fetch channel spec passive */
3575 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3576 hddLog(VOS_TRACE_LEVEL_ERROR,
3577 FL("attr channel spec passive failed"));
3578 goto fail;
3579 }
3580 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3581 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3582 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3583 pReqMsg->buckets[bktIndex].channels[j].passive);
3584 j++;
3585 }
3586 i++;
3587 }
3588 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3589 if (!HAL_STATUS_SUCCESS(status)) {
3590 hddLog(VOS_TRACE_LEVEL_ERROR,
3591 FL("sme_EXTScanStart failed(err=%d)"), status);
3592 vos_mem_free(pReqMsg);
3593 return -EINVAL;
3594 }
3595
3596 return 0;
3597
3598fail:
3599 vos_mem_free(pReqMsg);
3600 return -EINVAL;
3601}
3602
3603static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3604 struct wireless_dev *wdev,
3605 void *data, int dataLen)
3606{
3607 tpSirEXTScanStopReqParams pReqMsg = NULL;
3608 struct net_device *dev = wdev->netdev;
3609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3611 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3612 eHalStatus status;
3613
3614 status = wlan_hdd_validate_context(pHddCtx);
3615 if (0 != status)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR,
3618 FL("HDD context is not valid"));
3619 return -EINVAL;
3620 }
3621 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3622 data, dataLen,
3623 wlan_hdd_extscan_config_policy)) {
3624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3625 return -EINVAL;
3626 }
3627
3628 /* Parse and fetch request Id */
3629 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3631 return -EINVAL;
3632 }
3633
3634 pReqMsg = (tpSirEXTScanStopReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3635 if (!pReqMsg) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3637 return -ENOMEM;
3638 }
3639
3640 pReqMsg->requestId = nla_get_u32(
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3643
3644 pReqMsg->sessionId = pAdapter->sessionId;
3645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3646
3647 status = sme_EXTScanStop(pHddCtx->hHal, pReqMsg);
3648 if (!HAL_STATUS_SUCCESS(status)) {
3649 hddLog(VOS_TRACE_LEVEL_ERROR,
3650 FL("sme_EXTScanStop failed(err=%d)"), status);
3651 vos_mem_free(pReqMsg);
3652 return -EINVAL;
3653 }
3654
3655 return 0;
3656}
3657
3658static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3659 struct wireless_dev *wdev,
3660 void *data, int dataLen)
3661{
3662 tpSirEXTScanResetBssidHotlistReqParams pReqMsg = NULL;
3663 struct net_device *dev = wdev->netdev;
3664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3665 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3666 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3667 eHalStatus status;
3668
3669 status = wlan_hdd_validate_context(pHddCtx);
3670 if (0 != status)
3671 {
3672 hddLog(VOS_TRACE_LEVEL_ERROR,
3673 FL("HDD context is not valid"));
3674 return -EINVAL;
3675 }
3676 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3677 data, dataLen,
3678 wlan_hdd_extscan_config_policy)) {
3679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3680 return -EINVAL;
3681 }
3682
3683 /* Parse and fetch request Id */
3684 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3686 return -EINVAL;
3687 }
3688
3689 pReqMsg = (tpSirEXTScanResetBssidHotlistReqParams)
3690 vos_mem_malloc(sizeof(*pReqMsg));
3691 if (!pReqMsg) {
3692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3693 return -ENOMEM;
3694 }
3695
3696 pReqMsg->requestId = nla_get_u32(
3697 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3699
3700 pReqMsg->sessionId = pAdapter->sessionId;
3701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3702
3703 status = sme_ResetBssHotlist(pHddCtx->hHal, pReqMsg);
3704 if (!HAL_STATUS_SUCCESS(status)) {
3705 hddLog(VOS_TRACE_LEVEL_ERROR,
3706 FL("sme_ResetBssHotlist failed(err=%d)"), status);
3707 vos_mem_free(pReqMsg);
3708 return -EINVAL;
3709 }
3710
3711 return 0;
3712}
3713
3714static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3715 struct wiphy *wiphy,
3716 struct wireless_dev *wdev,
3717 void *data, int dataLen)
3718{
3719 tpSirEXTScanResetSignificantChangeReqParams pReqMsg = NULL;
3720 struct net_device *dev = wdev->netdev;
3721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3722 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3723 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3724 eHalStatus status;
3725
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3727 status = wlan_hdd_validate_context(pHddCtx);
3728 if (0 != status)
3729 {
3730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 FL("HDD context is not valid"));
3732 return -EINVAL;
3733 }
3734 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3735 data, dataLen,
3736 wlan_hdd_extscan_config_policy)) {
3737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3738 return -EINVAL;
3739 }
3740
3741 /* Parse and fetch request Id */
3742 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3744 return -EINVAL;
3745 }
3746
3747 pReqMsg = (tpSirEXTScanResetSignificantChangeReqParams)
3748 vos_mem_malloc(sizeof(*pReqMsg));
3749 if (!pReqMsg) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3751 return -ENOMEM;
3752 }
3753
3754 pReqMsg->requestId = nla_get_u32(
3755 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3757
3758 pReqMsg->sessionId = pAdapter->sessionId;
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3760
3761 status = sme_ResetSignificantChange(pHddCtx->hHal, pReqMsg);
3762 if (!HAL_STATUS_SUCCESS(status)) {
3763 hddLog(VOS_TRACE_LEVEL_ERROR,
3764 FL("sme_ResetSignificantChange failed(err=%d)"), status);
3765 vos_mem_free(pReqMsg);
3766 return -EINVAL;
3767 }
3768
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3770 return 0;
3771}
3772
3773#endif /* WLAN_FEATURE_EXTSCAN */
3774
Sunil Duttc69bccb2014-05-26 21:30:20 +05303775const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3776{
3777#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3778 {
3779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3782 WIPHY_VENDOR_CMD_NEED_NETDEV |
3783 WIPHY_VENDOR_CMD_NEED_RUNNING,
3784 .doit = wlan_hdd_cfg80211_ll_stats_clear
3785 },
3786
3787 {
3788 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3789 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3790 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3791 WIPHY_VENDOR_CMD_NEED_NETDEV |
3792 WIPHY_VENDOR_CMD_NEED_RUNNING,
3793 .doit = wlan_hdd_cfg80211_ll_stats_set
3794 },
3795
3796 {
3797 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3798 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3799 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3800 WIPHY_VENDOR_CMD_NEED_NETDEV |
3801 WIPHY_VENDOR_CMD_NEED_RUNNING,
3802 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303804#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805#ifdef WLAN_FEATURE_EXTSCAN
3806 {
3807 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3808 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3810 WIPHY_VENDOR_CMD_NEED_NETDEV |
3811 WIPHY_VENDOR_CMD_NEED_RUNNING,
3812 .doit = wlan_hdd_cfg80211_extscan_start
3813 },
3814 {
3815 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3816 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3818 WIPHY_VENDOR_CMD_NEED_NETDEV |
3819 WIPHY_VENDOR_CMD_NEED_RUNNING,
3820 .doit = wlan_hdd_cfg80211_extscan_stop
3821 },
3822 {
3823 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3824 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3825 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3826 WIPHY_VENDOR_CMD_NEED_NETDEV,
3827 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3828 },
3829 {
3830 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3831 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3832 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3833 WIPHY_VENDOR_CMD_NEED_NETDEV |
3834 WIPHY_VENDOR_CMD_NEED_RUNNING,
3835 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3836 },
3837 {
3838 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3839 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3840 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3841 WIPHY_VENDOR_CMD_NEED_NETDEV |
3842 WIPHY_VENDOR_CMD_NEED_RUNNING,
3843 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3844 },
3845 {
3846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3849 WIPHY_VENDOR_CMD_NEED_NETDEV |
3850 WIPHY_VENDOR_CMD_NEED_RUNNING,
3851 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3852 },
3853 {
3854 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3855 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3856 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3857 WIPHY_VENDOR_CMD_NEED_NETDEV |
3858 WIPHY_VENDOR_CMD_NEED_RUNNING,
3859 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3860 },
3861 {
3862 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3863 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3864 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3865 WIPHY_VENDOR_CMD_NEED_NETDEV |
3866 WIPHY_VENDOR_CMD_NEED_RUNNING,
3867 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3868 },
3869 {
3870 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3871 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3872 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3873 WIPHY_VENDOR_CMD_NEED_NETDEV |
3874 WIPHY_VENDOR_CMD_NEED_RUNNING,
3875 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3876 },
3877#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303878};
3879
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003880/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303881static const
3882struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003883{
3884#ifdef FEATURE_WLAN_CH_AVOID
3885 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303886 .vendor_id = QCA_NL80211_VENDOR_ID,
3887 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003888 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303889#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3890#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3891 {
3892 /* Index = 1*/
3893 .vendor_id = QCA_NL80211_VENDOR_ID,
3894 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3895 },
3896 {
3897 /* Index = 2*/
3898 .vendor_id = QCA_NL80211_VENDOR_ID,
3899 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3900 },
3901 {
3902 /* Index = 3*/
3903 .vendor_id = QCA_NL80211_VENDOR_ID,
3904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3905 },
3906 {
3907 /* Index = 4*/
3908 .vendor_id = QCA_NL80211_VENDOR_ID,
3909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3910 },
3911 {
3912 /* Index = 5*/
3913 .vendor_id = QCA_NL80211_VENDOR_ID,
3914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3915 },
3916 {
3917 /* Index = 6*/
3918 .vendor_id = QCA_NL80211_VENDOR_ID,
3919 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3920 },
3921#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922#ifdef WLAN_FEATURE_EXTSCAN
3923 {
3924 .vendor_id = QCA_NL80211_VENDOR_ID,
3925 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3926 },
3927 {
3928 .vendor_id = QCA_NL80211_VENDOR_ID,
3929 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3930 },
3931 {
3932 .vendor_id = QCA_NL80211_VENDOR_ID,
3933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3934 },
3935 {
3936 .vendor_id = QCA_NL80211_VENDOR_ID,
3937 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3938 },
3939 {
3940 .vendor_id = QCA_NL80211_VENDOR_ID,
3941 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3942 },
3943 {
3944 .vendor_id = QCA_NL80211_VENDOR_ID,
3945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3946 },
3947 {
3948 .vendor_id = QCA_NL80211_VENDOR_ID,
3949 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
3950 },
3951 {
3952 .vendor_id = QCA_NL80211_VENDOR_ID,
3953 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
3954 },
3955 {
3956 .vendor_id = QCA_NL80211_VENDOR_ID,
3957 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
3958 },
3959 {
3960 .vendor_id = QCA_NL80211_VENDOR_ID,
3961 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
3962 },
3963 {
3964 .vendor_id = QCA_NL80211_VENDOR_ID,
3965 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
3966 },
3967 {
3968 .vendor_id = QCA_NL80211_VENDOR_ID,
3969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
3970 },
3971 {
3972 .vendor_id = QCA_NL80211_VENDOR_ID,
3973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
3974 },
3975#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303976
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003977};
3978
Jeff Johnson295189b2012-06-20 16:38:30 -07003979/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303980 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303981 * This function is called by hdd_wlan_startup()
3982 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303983 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303985struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07003986{
3987 struct wiphy *wiphy;
3988 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303989 /*
3990 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 */
3992 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
3993
3994 if (!wiphy)
3995 {
3996 /* Print error and jump into err label and free the memory */
3997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
3998 return NULL;
3999 }
4000
Sunil Duttc69bccb2014-05-26 21:30:20 +05304001
Jeff Johnson295189b2012-06-20 16:38:30 -07004002 return wiphy;
4003}
4004
4005/*
4006 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 * private ioctl to change the band value
4009 */
4010int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4011{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304012 int i, j;
4013 eNVChannelEnabledType channelEnabledState;
4014
Jeff Johnsone7245742012-09-05 17:12:55 -07004015 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304016
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304017 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004018 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304019
4020 if (NULL == wiphy->bands[i])
4021 {
4022 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4023 __func__, i);
4024 continue;
4025 }
4026
4027 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4028 {
4029 struct ieee80211_supported_band *band = wiphy->bands[i];
4030
4031 channelEnabledState = vos_nv_getChannelEnabledState(
4032 band->channels[j].hw_value);
4033
4034 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4035 {
4036 // Enable Social channels for P2P
4037 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4038 NV_CHANNEL_ENABLE == channelEnabledState)
4039 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4040 else
4041 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4042 continue;
4043 }
4044 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4045 {
4046 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4047 continue;
4048 }
4049
4050 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4051 NV_CHANNEL_INVALID == channelEnabledState)
4052 {
4053 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4054 }
4055 else if (NV_CHANNEL_DFS == channelEnabledState)
4056 {
4057 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4058 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4059 }
4060 else
4061 {
4062 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4063 |IEEE80211_CHAN_RADAR);
4064 }
4065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004066 }
4067 return 0;
4068}
4069/*
4070 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 * This function is called by hdd_wlan_startup()
4072 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004073 * This function is used to initialize and register wiphy structure.
4074 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304075int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 struct wiphy *wiphy,
4077 hdd_config_t *pCfg
4078 )
4079{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304080 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304081 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4082
Jeff Johnsone7245742012-09-05 17:12:55 -07004083 ENTER();
4084
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 /* Now bind the underlying wlan device with wiphy */
4086 set_wiphy_dev(wiphy, dev);
4087
4088 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004089
Kiet Lam6c583332013-10-14 05:37:09 +05304090#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004091 /* the flag for the other case would be initialzed in
4092 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004093 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304094#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004095
Amar Singhalfddc28c2013-09-05 13:03:40 -07004096 /* This will disable updating of NL channels from passive to
4097 * active if a beacon is received on passive channel. */
4098 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004099
Amar Singhalfddc28c2013-09-05 13:03:40 -07004100
Amar Singhala49cbc52013-10-08 18:37:44 -07004101
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004103 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4104 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4105 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004106 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304107 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004109
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004111 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004112#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004113 || pCfg->isFastRoamIniFeatureEnabled
4114#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004115#ifdef FEATURE_WLAN_ESE
4116 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004117#endif
4118 )
4119 {
4120 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4121 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004122#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004123#ifdef FEATURE_WLAN_TDLS
4124 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4125 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4126#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304127#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304128 if (pCfg->configPNOScanSupport)
4129 {
4130 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4131 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4132 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4133 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4134 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304135#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004136
Amar Singhalfddc28c2013-09-05 13:03:40 -07004137#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004138 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4139 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004140 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004141 driver need to determine what to do with both
4142 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004143
4144 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004145#else
4146 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004148
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4150
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304151 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004152
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304153 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4154
Jeff Johnson295189b2012-06-20 16:38:30 -07004155 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304156 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4159 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 | BIT(NL80211_IFTYPE_AP);
4161
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304162 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004163 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4165 if( pCfg->enableMCC )
4166 {
4167 /* Currently, supports up to two channels */
4168 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004169
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304170 if( !pCfg->allowMCCGODiffBI )
4171 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004172
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304173 }
4174 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4175 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004176#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304177 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004178
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 /* Before registering we need to update the ht capabilitied based
4180 * on ini values*/
4181 if( !pCfg->ShortGI20MhzEnable )
4182 {
4183 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4184 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4185 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4186 }
4187
4188 if( !pCfg->ShortGI40MhzEnable )
4189 {
4190 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4191 }
4192
4193 if( !pCfg->nChannelBondingMode5GHz )
4194 {
4195 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4196 }
4197
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304198 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304199 if (true == hdd_is_5g_supported(pHddCtx))
4200 {
4201 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4202 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304203
4204 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4205 {
4206
4207 if (NULL == wiphy->bands[i])
4208 {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4210 __func__, i);
4211 continue;
4212 }
4213
4214 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4215 {
4216 struct ieee80211_supported_band *band = wiphy->bands[i];
4217
4218 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4219 {
4220 // Enable social channels for P2P
4221 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4222 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4223 else
4224 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4225 continue;
4226 }
4227 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4228 {
4229 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4230 continue;
4231 }
4232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 }
4234 /*Initialise the supported cipher suite details*/
4235 wiphy->cipher_suites = hdd_cipher_suites;
4236 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4237
4238 /*signal strength in mBm (100*dBm) */
4239 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4240
4241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 wiphy->max_remain_on_channel_duration = 1000;
4243#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004244
Sunil Duttc69bccb2014-05-26 21:30:20 +05304245 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4246 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004247 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4248 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4249
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304250 EXIT();
4251 return 0;
4252}
4253
4254/* In this function we are registering wiphy. */
4255int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4256{
4257 ENTER();
4258 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 if (0 > wiphy_register(wiphy))
4260 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304261 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4263 return -EIO;
4264 }
4265
4266 EXIT();
4267 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268}
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304270/* In this function we are updating channel list when,
4271 regulatory domain is FCC and country code is US.
4272 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4273 As per FCC smart phone is not a indoor device.
4274 GO should not opeate on indoor channels */
4275void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4276{
4277 int j;
4278 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4279 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4280 //Default counrtycode from NV at the time of wiphy initialization.
4281 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4282 &defaultCountryCode[0]))
4283 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004284 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304285 }
4286 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4287 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304288 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4289 {
4290 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4291 return;
4292 }
4293 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4294 {
4295 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4296 // Mark UNII -1 band channel as passive
4297 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4298 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4299 }
4300 }
4301}
4302
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304303/* This function registers for all frame which supplicant is interested in */
4304void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004305{
Jeff Johnson295189b2012-06-20 16:38:30 -07004306 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4307 /* Register for all P2P action, public action etc frames */
4308 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4309
Jeff Johnsone7245742012-09-05 17:12:55 -07004310 ENTER();
4311
Jeff Johnson295189b2012-06-20 16:38:30 -07004312 /* Right now we are registering these frame when driver is getting
4313 initialized. Once we will move to 2.6.37 kernel, in which we have
4314 frame register ops, we will move this code as a part of that */
4315 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304316 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4318
4319 /* GAS Initial Response */
4320 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4321 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304322
Jeff Johnson295189b2012-06-20 16:38:30 -07004323 /* GAS Comeback Request */
4324 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4325 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4326
4327 /* GAS Comeback Response */
4328 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4329 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4330
4331 /* P2P Public Action */
4332 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304333 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004334 P2P_PUBLIC_ACTION_FRAME_SIZE );
4335
4336 /* P2P Action */
4337 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4338 (v_U8_t*)P2P_ACTION_FRAME,
4339 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004340
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304341 /* WNM BSS Transition Request frame */
4342 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4343 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4344 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004345
4346 /* WNM-Notification */
4347 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4348 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4349 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004350}
4351
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304352void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004353{
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4355 /* Register for all P2P action, public action etc frames */
4356 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4357
Jeff Johnsone7245742012-09-05 17:12:55 -07004358 ENTER();
4359
Jeff Johnson295189b2012-06-20 16:38:30 -07004360 /* Right now we are registering these frame when driver is getting
4361 initialized. Once we will move to 2.6.37 kernel, in which we have
4362 frame register ops, we will move this code as a part of that */
4363 /* GAS Initial Request */
4364
4365 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4366 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4367
4368 /* GAS Initial Response */
4369 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4370 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304371
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 /* GAS Comeback Request */
4373 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4374 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4375
4376 /* GAS Comeback Response */
4377 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4378 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4379
4380 /* P2P Public Action */
4381 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304382 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 P2P_PUBLIC_ACTION_FRAME_SIZE );
4384
4385 /* P2P Action */
4386 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4387 (v_U8_t*)P2P_ACTION_FRAME,
4388 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004389 /* WNM-Notification */
4390 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4391 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4392 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004393}
4394
4395#ifdef FEATURE_WLAN_WAPI
4396void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4397 const u8 *mac_addr, u8 *key , int key_Len)
4398{
4399 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4400 tCsrRoamSetKey setKey;
4401 v_BOOL_t isConnected = TRUE;
4402 int status = 0;
4403 v_U32_t roamId= 0xFF;
4404 tANI_U8 *pKeyPtr = NULL;
4405 int n = 0;
4406
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304407 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4408 __func__, hdd_device_modetoString(pAdapter->device_mode),
4409 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004410
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304411 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 setKey.keyId = key_index; // Store Key ID
4413 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4414 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4415 setKey.paeRole = 0 ; // the PAE role
4416 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4417 {
4418 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4419 }
4420 else
4421 {
4422 isConnected = hdd_connIsConnected(pHddStaCtx);
4423 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4424 }
4425 setKey.keyLength = key_Len;
4426 pKeyPtr = setKey.Key;
4427 memcpy( pKeyPtr, key, key_Len);
4428
Arif Hussain6d2a3322013-11-17 19:50:10 -08004429 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 __func__, key_Len);
4431 for (n = 0 ; n < key_Len; n++)
4432 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4433 __func__,n,setKey.Key[n]);
4434
4435 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4436 if ( isConnected )
4437 {
4438 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4439 pAdapter->sessionId, &setKey, &roamId );
4440 }
4441 if ( status != 0 )
4442 {
4443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4444 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4445 __LINE__, status );
4446 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4447 }
4448}
4449#endif /* FEATURE_WLAN_WAPI*/
4450
4451#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304452int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 beacon_data_t **ppBeacon,
4454 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004455#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304456int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004457 beacon_data_t **ppBeacon,
4458 struct cfg80211_beacon_data *params,
4459 int dtim_period)
4460#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304461{
Jeff Johnson295189b2012-06-20 16:38:30 -07004462 int size;
4463 beacon_data_t *beacon = NULL;
4464 beacon_data_t *old = NULL;
4465 int head_len,tail_len;
4466
Jeff Johnsone7245742012-09-05 17:12:55 -07004467 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304469 {
4470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4471 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004472 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004474
4475 old = pAdapter->sessionCtx.ap.beacon;
4476
4477 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304478 {
4479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4480 FL("session(%d) old and new heads points to NULL"),
4481 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004482 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304483 }
4484
4485 if (params->tail && !params->tail_len)
4486 {
4487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4488 FL("tail_len is zero but tail is not NULL"));
4489 return -EINVAL;
4490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004491
Jeff Johnson295189b2012-06-20 16:38:30 -07004492#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4493 /* Kernel 3.0 is not updating dtim_period for set beacon */
4494 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304495 {
4496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4497 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004498 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004500#endif
4501
4502 if(params->head)
4503 head_len = params->head_len;
4504 else
4505 head_len = old->head_len;
4506
4507 if(params->tail || !old)
4508 tail_len = params->tail_len;
4509 else
4510 tail_len = old->tail_len;
4511
4512 size = sizeof(beacon_data_t) + head_len + tail_len;
4513
4514 beacon = kzalloc(size, GFP_KERNEL);
4515
4516 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304517 {
4518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4519 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304521 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004522
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004523#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 if(params->dtim_period || !old )
4525 beacon->dtim_period = params->dtim_period;
4526 else
4527 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004528#else
4529 if(dtim_period || !old )
4530 beacon->dtim_period = dtim_period;
4531 else
4532 beacon->dtim_period = old->dtim_period;
4533#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304534
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4536 beacon->tail = beacon->head + head_len;
4537 beacon->head_len = head_len;
4538 beacon->tail_len = tail_len;
4539
4540 if(params->head) {
4541 memcpy (beacon->head,params->head,beacon->head_len);
4542 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304543 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 if(old)
4545 memcpy (beacon->head,old->head,beacon->head_len);
4546 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304547
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 if(params->tail) {
4549 memcpy (beacon->tail,params->tail,beacon->tail_len);
4550 }
4551 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304552 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 memcpy (beacon->tail,old->tail,beacon->tail_len);
4554 }
4555
4556 *ppBeacon = beacon;
4557
4558 kfree(old);
4559
4560 return 0;
4561
4562}
Jeff Johnson295189b2012-06-20 16:38:30 -07004563
4564v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4565{
4566 int left = length;
4567 v_U8_t *ptr = pIes;
4568 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304569
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 elem_id = ptr[0];
4573 elem_len = ptr[1];
4574 left -= 2;
4575 if(elem_len > left)
4576 {
4577 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004578 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004579 eid,elem_len,left);
4580 return NULL;
4581 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304582 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 {
4584 return ptr;
4585 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304586
Jeff Johnson295189b2012-06-20 16:38:30 -07004587 left -= elem_len;
4588 ptr += (elem_len + 2);
4589 }
4590 return NULL;
4591}
4592
Jeff Johnson295189b2012-06-20 16:38:30 -07004593/* Check if rate is 11g rate or not */
4594static int wlan_hdd_rate_is_11g(u8 rate)
4595{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004596 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 u8 i;
4598 for (i = 0; i < 8; i++)
4599 {
4600 if(rate == gRateArray[i])
4601 return TRUE;
4602 }
4603 return FALSE;
4604}
4605
4606/* Check for 11g rate and set proper 11g only mode */
4607static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4608 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4609{
4610 u8 i, num_rates = pIe[0];
4611
4612 pIe += 1;
4613 for ( i = 0; i < num_rates; i++)
4614 {
4615 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4616 {
4617 /* If rate set have 11g rate than change the mode to 11G */
4618 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4619 if (pIe[i] & BASIC_RATE_MASK)
4620 {
4621 /* If we have 11g rate as basic rate, it means mode
4622 is 11g only mode.
4623 */
4624 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4625 *pCheckRatesfor11g = FALSE;
4626 }
4627 }
4628 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4629 {
4630 *require_ht = TRUE;
4631 }
4632 }
4633 return;
4634}
4635
4636static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4637{
4638 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4639 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4640 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4641 u8 checkRatesfor11g = TRUE;
4642 u8 require_ht = FALSE;
4643 u8 *pIe=NULL;
4644
4645 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4646
4647 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4648 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4649 if (pIe != NULL)
4650 {
4651 pIe += 1;
4652 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4653 &pConfig->SapHw_mode);
4654 }
4655
4656 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4657 WLAN_EID_EXT_SUPP_RATES);
4658 if (pIe != NULL)
4659 {
4660
4661 pIe += 1;
4662 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4663 &pConfig->SapHw_mode);
4664 }
4665
4666 if( pConfig->channel > 14 )
4667 {
4668 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4669 }
4670
4671 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4672 WLAN_EID_HT_CAPABILITY);
4673
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304674 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 {
4676 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4677 if(require_ht)
4678 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4679 }
4680}
4681
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304682static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4683 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4684{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004685 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304686 v_U8_t *pIe = NULL;
4687 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4688
4689 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4690 pBeacon->tail, pBeacon->tail_len);
4691
4692 if (pIe)
4693 {
4694 ielen = pIe[1] + 2;
4695 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4696 {
4697 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4698 }
4699 else
4700 {
4701 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4702 return -EINVAL;
4703 }
4704 *total_ielen += ielen;
4705 }
4706 return 0;
4707}
4708
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004709static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4710 v_U8_t *genie, v_U8_t *total_ielen)
4711{
4712 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4713 int left = pBeacon->tail_len;
4714 v_U8_t *ptr = pBeacon->tail;
4715 v_U8_t elem_id, elem_len;
4716 v_U16_t ielen = 0;
4717
4718 if ( NULL == ptr || 0 == left )
4719 return;
4720
4721 while (left >= 2)
4722 {
4723 elem_id = ptr[0];
4724 elem_len = ptr[1];
4725 left -= 2;
4726 if (elem_len > left)
4727 {
4728 hddLog( VOS_TRACE_LEVEL_ERROR,
4729 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4730 elem_id, elem_len, left);
4731 return;
4732 }
4733 if (IE_EID_VENDOR == elem_id)
4734 {
4735 /* skipping the VSIE's which we don't want to include or
4736 * it will be included by existing code
4737 */
4738 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4739#ifdef WLAN_FEATURE_WFD
4740 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4741#endif
4742 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4743 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4744 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4745 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4746 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4747 {
4748 ielen = ptr[1] + 2;
4749 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4750 {
4751 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4752 *total_ielen += ielen;
4753 }
4754 else
4755 {
4756 hddLog( VOS_TRACE_LEVEL_ERROR,
4757 "IE Length is too big "
4758 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4759 elem_id, elem_len, *total_ielen);
4760 }
4761 }
4762 }
4763
4764 left -= elem_len;
4765 ptr += (elem_len + 2);
4766 }
4767 return;
4768}
4769
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004770#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004771static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4772 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004773#else
4774static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4775 struct cfg80211_beacon_data *params)
4776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004777{
4778 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304779 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004780 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004781 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004782
4783 genie = vos_mem_malloc(MAX_GENIE_LEN);
4784
4785 if(genie == NULL) {
4786
4787 return -ENOMEM;
4788 }
4789
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304790 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4791 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304793 hddLog(LOGE,
4794 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304795 ret = -EINVAL;
4796 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004797 }
4798
4799#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304800 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4801 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4802 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304803 hddLog(LOGE,
4804 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304805 ret = -EINVAL;
4806 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 }
4808#endif
4809
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304810 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4811 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004812 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304813 hddLog(LOGE,
4814 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304815 ret = -EINVAL;
4816 goto done;
4817 }
4818
4819 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4820 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004821 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004823
4824 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4825 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4826 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4827 {
4828 hddLog(LOGE,
4829 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004830 ret = -EINVAL;
4831 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 }
4833
4834 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4835 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4836 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4837 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4838 ==eHAL_STATUS_FAILURE)
4839 {
4840 hddLog(LOGE,
4841 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004842 ret = -EINVAL;
4843 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 }
4845
4846 // Added for ProResp IE
4847 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4848 {
4849 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4850 u8 probe_rsp_ie_len[3] = {0};
4851 u8 counter = 0;
4852 /* Check Probe Resp Length if it is greater then 255 then Store
4853 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4854 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4855 Store More then 255 bytes into One Variable.
4856 */
4857 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4858 {
4859 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4860 {
4861 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4862 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4863 }
4864 else
4865 {
4866 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4867 rem_probe_resp_ie_len = 0;
4868 }
4869 }
4870
4871 rem_probe_resp_ie_len = 0;
4872
4873 if (probe_rsp_ie_len[0] > 0)
4874 {
4875 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4876 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4877 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4878 probe_rsp_ie_len[0], NULL,
4879 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4880 {
4881 hddLog(LOGE,
4882 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004883 ret = -EINVAL;
4884 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 }
4886 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4887 }
4888
4889 if (probe_rsp_ie_len[1] > 0)
4890 {
4891 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4892 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4893 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4894 probe_rsp_ie_len[1], NULL,
4895 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4896 {
4897 hddLog(LOGE,
4898 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004899 ret = -EINVAL;
4900 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 }
4902 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4903 }
4904
4905 if (probe_rsp_ie_len[2] > 0)
4906 {
4907 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4908 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4909 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4910 probe_rsp_ie_len[2], NULL,
4911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4912 {
4913 hddLog(LOGE,
4914 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004915 ret = -EINVAL;
4916 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 }
4918 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4919 }
4920
4921 if (probe_rsp_ie_len[1] == 0 )
4922 {
4923 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4924 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4925 eANI_BOOLEAN_FALSE) )
4926 {
4927 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004928 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004929 }
4930 }
4931
4932 if (probe_rsp_ie_len[2] == 0 )
4933 {
4934 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4935 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4936 eANI_BOOLEAN_FALSE) )
4937 {
4938 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004939 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 }
4941 }
4942
4943 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4944 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4945 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4946 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4947 == eHAL_STATUS_FAILURE)
4948 {
4949 hddLog(LOGE,
4950 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004951 ret = -EINVAL;
4952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 }
4954 }
4955 else
4956 {
4957 // Reset WNI_CFG_PROBE_RSP Flags
4958 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
4959
4960 hddLog(VOS_TRACE_LEVEL_INFO,
4961 "%s: No Probe Response IE received in set beacon",
4962 __func__);
4963 }
4964
4965 // Added for AssocResp IE
4966 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
4967 {
4968 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4969 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
4970 params->assocresp_ies_len, NULL,
4971 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4972 {
4973 hddLog(LOGE,
4974 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004975 ret = -EINVAL;
4976 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 }
4978
4979 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4980 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
4981 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4982 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4983 == eHAL_STATUS_FAILURE)
4984 {
4985 hddLog(LOGE,
4986 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004987 ret = -EINVAL;
4988 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 }
4990 }
4991 else
4992 {
4993 hddLog(VOS_TRACE_LEVEL_INFO,
4994 "%s: No Assoc Response IE received in set beacon",
4995 __func__);
4996
4997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
4999 eANI_BOOLEAN_FALSE) )
5000 {
5001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005003 }
5004 }
5005
Jeff Johnsone7245742012-09-05 17:12:55 -07005006done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305008 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005009}
Jeff Johnson295189b2012-06-20 16:38:30 -07005010
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305011/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 * FUNCTION: wlan_hdd_validate_operation_channel
5013 * called by wlan_hdd_cfg80211_start_bss() and
5014 * wlan_hdd_cfg80211_set_channel()
5015 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305016 * channel list.
5017 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005018VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305020
Jeff Johnson295189b2012-06-20 16:38:30 -07005021 v_U32_t num_ch = 0;
5022 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5023 u32 indx = 0;
5024 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305025 v_U8_t fValidChannel = FALSE, count = 0;
5026 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305027
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5029
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305030 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305032 /* Validate the channel */
5033 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005034 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305035 if ( channel == rfChannels[count].channelNum )
5036 {
5037 fValidChannel = TRUE;
5038 break;
5039 }
5040 }
5041 if (fValidChannel != TRUE)
5042 {
5043 hddLog(VOS_TRACE_LEVEL_ERROR,
5044 "%s: Invalid Channel [%d]", __func__, channel);
5045 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 }
5047 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305048 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305050 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5051 valid_ch, &num_ch))
5052 {
5053 hddLog(VOS_TRACE_LEVEL_ERROR,
5054 "%s: failed to get valid channel list", __func__);
5055 return VOS_STATUS_E_FAILURE;
5056 }
5057 for (indx = 0; indx < num_ch; indx++)
5058 {
5059 if (channel == valid_ch[indx])
5060 {
5061 break;
5062 }
5063 }
5064
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305065 if (indx >= num_ch)
5066 {
5067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5068 {
5069 eCsrBand band;
5070 unsigned int freq;
5071
5072 sme_GetFreqBand(hHal, &band);
5073
5074 if (eCSR_BAND_5G == band)
5075 {
5076#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5077 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5078 {
5079 freq = ieee80211_channel_to_frequency(channel,
5080 IEEE80211_BAND_2GHZ);
5081 }
5082 else
5083 {
5084 freq = ieee80211_channel_to_frequency(channel,
5085 IEEE80211_BAND_5GHZ);
5086 }
5087#else
5088 freq = ieee80211_channel_to_frequency(channel);
5089#endif
5090 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5091 return VOS_STATUS_SUCCESS;
5092 }
5093 }
5094
5095 hddLog(VOS_TRACE_LEVEL_ERROR,
5096 "%s: Invalid Channel [%d]", __func__, channel);
5097 return VOS_STATUS_E_FAILURE;
5098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305100
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305102
Jeff Johnson295189b2012-06-20 16:38:30 -07005103}
5104
Viral Modi3a32cc52013-02-08 11:14:52 -08005105/**
5106 * FUNCTION: wlan_hdd_cfg80211_set_channel
5107 * This function is used to set the channel number
5108 */
5109static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5110 struct ieee80211_channel *chan,
5111 enum nl80211_channel_type channel_type
5112 )
5113{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305114 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005115 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005116 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005117 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305118 hdd_context_t *pHddCtx;
5119 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005120
5121 ENTER();
5122
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305123
Viral Modi3a32cc52013-02-08 11:14:52 -08005124 if( NULL == dev )
5125 {
5126 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005127 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005128 return -ENODEV;
5129 }
5130 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Sushant Kaushik10728722014-05-14 16:20:25 +05305131 if (NULL == pAdapter)
5132 {
5133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5134 "%s: HDD adapter context is Null", __func__);
5135 return -ENODEV;
5136 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305137 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5138 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5139 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005140 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305141 "%s: device_mode = %s (%d) freq = %d", __func__,
5142 hdd_device_modetoString(pAdapter->device_mode),
5143 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305144
5145 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5146 status = wlan_hdd_validate_context(pHddCtx);
5147
5148 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005149 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5151 "%s: HDD context is not valid", __func__);
5152 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005153 }
5154
5155 /*
5156 * Do freq to chan conversion
5157 * TODO: for 11a
5158 */
5159
5160 channel = ieee80211_frequency_to_channel(freq);
5161
5162 /* Check freq range */
5163 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5164 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5165 {
5166 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005167 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005168 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5169 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5170 return -EINVAL;
5171 }
5172
5173 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5174
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305175 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5176 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005177 {
5178 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5179 {
5180 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005181 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005182 return -EINVAL;
5183 }
5184 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5185 "%s: set channel to [%d] for device mode =%d",
5186 __func__, channel,pAdapter->device_mode);
5187 }
5188 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005189 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005190 )
5191 {
5192 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5193 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5194 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5195
5196 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5197 {
5198 /* Link is up then return cant set channel*/
5199 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005200 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005201 return -EINVAL;
5202 }
5203
5204 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5205 pHddStaCtx->conn_info.operationChannel = channel;
5206 pRoamProfile->ChannelInfo.ChannelList =
5207 &pHddStaCtx->conn_info.operationChannel;
5208 }
5209 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005210 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005211 )
5212 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305213 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5214 {
5215 if(VOS_STATUS_SUCCESS !=
5216 wlan_hdd_validate_operation_channel(pAdapter,channel))
5217 {
5218 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005219 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305220 return -EINVAL;
5221 }
5222 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5223 }
5224 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005225 {
5226 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5227
5228 /* If auto channel selection is configured as enable/ 1 then ignore
5229 channel set by supplicant
5230 */
5231 if ( cfg_param->apAutoChannelSelection )
5232 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305233 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5234 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005235 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305236 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5237 __func__, hdd_device_modetoString(pAdapter->device_mode),
5238 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005239 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305240 else
5241 {
5242 if(VOS_STATUS_SUCCESS !=
5243 wlan_hdd_validate_operation_channel(pAdapter,channel))
5244 {
5245 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005246 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305247 return -EINVAL;
5248 }
5249 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5250 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005251 }
5252 }
5253 else
5254 {
5255 hddLog(VOS_TRACE_LEVEL_FATAL,
5256 "%s: Invalid device mode failed to set valid channel", __func__);
5257 return -EINVAL;
5258 }
5259 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305260 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005261}
5262
Jeff Johnson295189b2012-06-20 16:38:30 -07005263#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5264static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5265 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005266#else
5267static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5268 struct cfg80211_beacon_data *params,
5269 const u8 *ssid, size_t ssid_len,
5270 enum nl80211_hidden_ssid hidden_ssid)
5271#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005272{
5273 tsap_Config_t *pConfig;
5274 beacon_data_t *pBeacon = NULL;
5275 struct ieee80211_mgmt *pMgmt_frame;
5276 v_U8_t *pIe=NULL;
5277 v_U16_t capab_info;
5278 eCsrAuthType RSNAuthType;
5279 eCsrEncryptionType RSNEncryptType;
5280 eCsrEncryptionType mcRSNEncryptType;
5281 int status = VOS_STATUS_SUCCESS;
5282 tpWLAN_SAPEventCB pSapEventCallback;
5283 hdd_hostapd_state_t *pHostapdState;
5284 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5285 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305286 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305288 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005289 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005290 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005291 v_BOOL_t MFPCapable = VOS_FALSE;
5292 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305293 eHddDot11Mode sapDot11Mode =
5294 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005295
5296 ENTER();
5297
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305298 iniConfig = pHddCtx->cfg_ini;
5299
Jeff Johnson295189b2012-06-20 16:38:30 -07005300 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5301
5302 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5303
5304 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5305
5306 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5307
5308 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5309
5310 //channel is already set in the set_channel Call back
5311 //pConfig->channel = pCommitConfig->channel;
5312
5313 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305314 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005315 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5316
5317 pConfig->dtim_period = pBeacon->dtim_period;
5318
Arif Hussain6d2a3322013-11-17 19:50:10 -08005319 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 pConfig->dtim_period);
5321
5322
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005323 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005324 {
5325 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005326 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305327 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5328 {
5329 tANI_BOOLEAN restartNeeded;
5330 pConfig->ieee80211d = 1;
5331 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5332 sme_setRegInfo(hHal, pConfig->countryCode);
5333 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5334 }
5335 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005336 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005337 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005338 pConfig->ieee80211d = 1;
5339 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5340 sme_setRegInfo(hHal, pConfig->countryCode);
5341 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005342 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005343 else
5344 {
5345 pConfig->ieee80211d = 0;
5346 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305347 /*
5348 * If auto channel is configured i.e. channel is 0,
5349 * so skip channel validation.
5350 */
5351 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5352 {
5353 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5354 {
5355 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005356 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305357 return -EINVAL;
5358 }
5359 }
5360 else
5361 {
5362 if(1 != pHddCtx->is_dynamic_channel_range_set)
5363 {
5364 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5365 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5366 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5367 }
5368 pHddCtx->is_dynamic_channel_range_set = 0;
5369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005370 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005371 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 {
5373 pConfig->ieee80211d = 0;
5374 }
5375 pConfig->authType = eSAP_AUTO_SWITCH;
5376
5377 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305378
5379 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5381
5382 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5383
5384 /*Set wps station to configured*/
5385 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5386
5387 if(pIe)
5388 {
5389 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5390 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005391 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 return -EINVAL;
5393 }
5394 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5395 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005396 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005397 /* Check 15 bit of WPS IE as it contain information for wps state
5398 * WPS state
5399 */
5400 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5401 {
5402 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5403 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5404 {
5405 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5406 }
5407 }
5408 }
5409 else
5410 {
5411 pConfig->wps_state = SAP_WPS_DISABLED;
5412 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305413 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005414
c_hpothufe599e92014-06-16 11:38:55 +05305415 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5416 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5417 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5418 eCSR_ENCRYPT_TYPE_NONE;
5419
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 pConfig->RSNWPAReqIELength = 0;
5421 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305422 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 WLAN_EID_RSN);
5424 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305425 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5427 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5428 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305429 /* The actual processing may eventually be more extensive than
5430 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 * by the app.
5432 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305433 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5435 &RSNEncryptType,
5436 &mcRSNEncryptType,
5437 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005438 &MFPCapable,
5439 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 pConfig->pRSNWPAReqIE[1]+2,
5441 pConfig->pRSNWPAReqIE );
5442
5443 if( VOS_STATUS_SUCCESS == status )
5444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305445 /* Now copy over all the security attributes you have
5446 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005447 * */
5448 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5449 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5450 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5451 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305452 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005453 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5455 }
5456 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305457
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5459 pBeacon->tail, pBeacon->tail_len);
5460
5461 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5462 {
5463 if (pConfig->pRSNWPAReqIE)
5464 {
5465 /*Mixed mode WPA/WPA2*/
5466 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5467 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5468 }
5469 else
5470 {
5471 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5472 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5473 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305474 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5476 &RSNEncryptType,
5477 &mcRSNEncryptType,
5478 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005479 &MFPCapable,
5480 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005481 pConfig->pRSNWPAReqIE[1]+2,
5482 pConfig->pRSNWPAReqIE );
5483
5484 if( VOS_STATUS_SUCCESS == status )
5485 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305486 /* Now copy over all the security attributes you have
5487 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 * */
5489 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5490 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5491 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5492 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305493 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005494 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5496 }
5497 }
5498 }
5499
Jeff Johnson4416a782013-03-25 14:17:50 -07005500 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5501 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5502 return -EINVAL;
5503 }
5504
Jeff Johnson295189b2012-06-20 16:38:30 -07005505 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5506
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005507#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 if (params->ssid != NULL)
5509 {
5510 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5511 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5512 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5513 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5514 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005515#else
5516 if (ssid != NULL)
5517 {
5518 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5519 pConfig->SSIDinfo.ssid.length = ssid_len;
5520 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5521 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5522 }
5523#endif
5524
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305525 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 /* default value */
5529 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5530 pConfig->num_accept_mac = 0;
5531 pConfig->num_deny_mac = 0;
5532
5533 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5534 pBeacon->tail, pBeacon->tail_len);
5535
5536 /* pIe for black list is following form:
5537 type : 1 byte
5538 length : 1 byte
5539 OUI : 4 bytes
5540 acl type : 1 byte
5541 no of mac addr in black list: 1 byte
5542 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305543 */
5544 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 {
5546 pConfig->SapMacaddr_acl = pIe[6];
5547 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005548 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305550 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5551 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5553 for (i = 0; i < pConfig->num_deny_mac; i++)
5554 {
5555 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5556 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 }
5559 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5560 pBeacon->tail, pBeacon->tail_len);
5561
5562 /* pIe for white list is following form:
5563 type : 1 byte
5564 length : 1 byte
5565 OUI : 4 bytes
5566 acl type : 1 byte
5567 no of mac addr in white list: 1 byte
5568 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305569 */
5570 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 {
5572 pConfig->SapMacaddr_acl = pIe[6];
5573 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005574 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305576 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5577 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5579 for (i = 0; i < pConfig->num_accept_mac; i++)
5580 {
5581 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5582 acl_entry++;
5583 }
5584 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305585
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5587
Jeff Johnsone7245742012-09-05 17:12:55 -07005588#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005589 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305590 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5591 * 11ac in .ini and 11ac is supported by both host and firmware.
5592 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5593 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005594 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5595 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305596 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5597 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5598 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5599 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5600 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005601 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305602 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005603 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305604 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005605
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305606 /* If ACS disable and selected channel <= 14
5607 * OR
5608 * ACS enabled and ACS operating band is choosen as 2.4
5609 * AND
5610 * VHT in 2.4G Disabled
5611 * THEN
5612 * Fallback to 11N mode
5613 */
5614 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5615 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305616 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305617 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005618 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305619 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5620 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005621 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5622 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005623 }
5624#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305625
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005626 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5627 {
5628 sme_SelectCBMode(hHal,
5629 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5630 pConfig->channel);
5631 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 // ht_capab is not what the name conveys,this is used for protection bitmap
5633 pConfig->ht_capab =
5634 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5635
5636 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5637 {
5638 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5639 return -EINVAL;
5640 }
5641
5642 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305643 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5645 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646 pConfig->obssProtEnabled =
5647 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005648
Chet Lanctot8cecea22014-02-11 19:09:36 -08005649#ifdef WLAN_FEATURE_11W
5650 pConfig->mfpCapable = MFPCapable;
5651 pConfig->mfpRequired = MFPRequired;
5652 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5653 pConfig->mfpCapable, pConfig->mfpRequired);
5654#endif
5655
Arif Hussain6d2a3322013-11-17 19:50:10 -08005656 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005657 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005658 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5659 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5660 (int)pConfig->channel);
5661 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5662 pConfig->SapHw_mode, pConfig->privacy,
5663 pConfig->authType);
5664 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5665 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5666 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5667 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005668
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305669 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 {
5671 //Bss already started. just return.
5672 //TODO Probably it should update some beacon params.
5673 hddLog( LOGE, "Bss Already started...Ignore the request");
5674 EXIT();
5675 return 0;
5676 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305677
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 pConfig->persona = pHostapdAdapter->device_mode;
5679
5680 pSapEventCallback = hdd_hostapd_SAPEventCB;
5681 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5682 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5683 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005684 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 return -EINVAL;
5686 }
5687
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305688 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5690
5691 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305692
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305694 {
5695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005696 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005697 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 VOS_ASSERT(0);
5699 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305700
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
5702
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005703#ifdef WLAN_FEATURE_P2P_DEBUG
5704 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5705 {
5706 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5707 {
5708 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5709 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005710 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005711 }
5712 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5713 {
5714 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5715 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005716 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005717 }
5718 }
5719#endif
5720
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 pHostapdState->bCommit = TRUE;
5722 EXIT();
5723
5724 return 0;
5725}
5726
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005727#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305728static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5729 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 struct beacon_parameters *params)
5731{
5732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik10728722014-05-14 16:20:25 +05305733 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305734 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005735
5736 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05305737 if (NULL == pAdapter)
5738 {
5739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5740 "%s: HDD adapter context is Null", __func__);
5741 return -ENODEV;
5742 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305743 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5744 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5745 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305746 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5747 hdd_device_modetoString(pAdapter->device_mode),
5748 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005749
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5751 status = wlan_hdd_validate_context(pHddCtx);
5752
5753 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005754 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5756 "%s: HDD context is not valid", __func__);
5757 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005758 }
5759
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305760 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 )
5763 {
5764 beacon_data_t *old,*new;
5765
5766 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305767
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305769 {
5770 hddLog(VOS_TRACE_LEVEL_WARN,
5771 FL("already beacon info added to session(%d)"),
5772 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305774 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005775
5776 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5777
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305778 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 {
5780 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005781 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 return -EINVAL;
5783 }
5784
5785 pAdapter->sessionCtx.ap.beacon = new;
5786
5787 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5788 }
5789
5790 EXIT();
5791 return status;
5792}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305793
5794static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 struct net_device *dev,
5796 struct beacon_parameters *params)
5797{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik10728722014-05-14 16:20:25 +05305799 hdd_station_ctx_t *pHddStaCtx = NULL;
5800 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305801 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005802
5803 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05305804 if (NULL == pAdapter)
5805 {
5806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5807 "%s: HDD adapter context is Null", __func__);
5808 return -ENODEV;
5809 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sushant Kaushik10728722014-05-14 16:20:25 +05305811 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305812 status = wlan_hdd_validate_context(pHddCtx);
5813
5814 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005815 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5817 "%s: HDD context is not valid", __func__);
5818 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005819 }
Sushant Kaushik10728722014-05-14 16:20:25 +05305820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5821 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5822 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5824 __func__, hdd_device_modetoString(pAdapter->device_mode),
5825 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 {
5830 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305831
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305833
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305835 {
5836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5837 FL("session(%d) old and new heads points to NULL"),
5838 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005839 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305840 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005841
5842 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5843
5844 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005846 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 return -EINVAL;
5848 }
5849
5850 pAdapter->sessionCtx.ap.beacon = new;
5851
5852 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5853 }
5854
5855 EXIT();
5856 return status;
5857}
5858
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005859#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5860
5861#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005862static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5863 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005864#else
5865static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5866 struct net_device *dev)
5867#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005868{
5869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005870 hdd_context_t *pHddCtx = NULL;
5871 hdd_scaninfo_t *pScanInfo = NULL;
5872 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305873 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305874 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005875
5876 ENTER();
5877
5878 if (NULL == pAdapter)
5879 {
Sushant Kaushik10728722014-05-14 16:20:25 +05305880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005881 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 return -ENODEV;
5883 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005884
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305885 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5886 TRACE_CODE_HDD_CFG80211_STOP_AP,
5887 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5889 status = wlan_hdd_validate_context(pHddCtx);
5890
5891 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005892 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5894 "%s: HDD context is not valid", __func__);
5895 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005896 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005897
5898 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5899 if (NULL == staAdapter)
5900 {
5901 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5902 if (NULL == staAdapter)
5903 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5905 "%s: HDD adapter context for STA/P2P-CLI is Null",
5906 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005907 }
5908 }
5909
5910 pScanInfo = &pHddCtx->scan_info;
5911
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5913 __func__, hdd_device_modetoString(pAdapter->device_mode),
5914 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005915
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305916 ret = wlan_hdd_scan_abort(pAdapter);
5917
Girish Gowli4bf7a632014-06-12 13:42:11 +05305918 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005919 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5921 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305922
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305923 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005924 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5926 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005927
Jeff Johnsone7245742012-09-05 17:12:55 -07005928 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305929 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005930 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305931 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005932 }
5933
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305934 hdd_hostapd_stop(dev);
5935
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 )
5939 {
5940 beacon_data_t *old;
5941
5942 old = pAdapter->sessionCtx.ap.beacon;
5943
5944 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305945 {
5946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5947 FL("session(%d) beacon data points to NULL"),
5948 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005951
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005953
5954 mutex_lock(&pHddCtx->sap_lock);
5955 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
5956 {
Jeff Johnson4416a782013-03-25 14:17:50 -07005957 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 {
5959 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5960
5961 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
5962
5963 if (!VOS_IS_STATUS_SUCCESS(status))
5964 {
5965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005966 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305968 }
5969 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
5971 }
5972 mutex_unlock(&pHddCtx->sap_lock);
5973
5974 if(status != VOS_STATUS_SUCCESS)
5975 {
5976 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005977 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 return -EINVAL;
5979 }
5980
Jeff Johnson4416a782013-03-25 14:17:50 -07005981 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
5983 ==eHAL_STATUS_FAILURE)
5984 {
5985 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005986 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 }
5988
Jeff Johnson4416a782013-03-25 14:17:50 -07005989 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5991 eANI_BOOLEAN_FALSE) )
5992 {
5993 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005994 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 }
5996
5997 // Reset WNI_CFG_PROBE_RSP Flags
5998 wlan_hdd_reset_prob_rspies(pAdapter);
5999
6000 pAdapter->sessionCtx.ap.beacon = NULL;
6001 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006002#ifdef WLAN_FEATURE_P2P_DEBUG
6003 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6004 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6005 {
6006 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6007 "GO got removed");
6008 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6009 }
6010#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 }
6012 EXIT();
6013 return status;
6014}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006015
6016#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6017
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306018static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6019 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006020 struct cfg80211_ap_settings *params)
6021{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306022 hdd_adapter_t *pAdapter;
6023 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306024 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006025
6026 ENTER();
6027
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306028 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006029 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306031 "%s: Device is Null", __func__);
6032 return -ENODEV;
6033 }
6034
6035 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6036 if (NULL == pAdapter)
6037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306039 "%s: HDD adapter is Null", __func__);
6040 return -ENODEV;
6041 }
6042
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306043 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6044 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6045 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306046 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6047 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306049 "%s: HDD adapter magic is invalid", __func__);
6050 return -ENODEV;
6051 }
6052
6053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306054 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306055
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306056 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306057 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6059 "%s: HDD context is not valid", __func__);
6060 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306061 }
6062
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306063 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6064 __func__, hdd_device_modetoString(pAdapter->device_mode),
6065 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306066
6067 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006068 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006069 )
6070 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306071 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006072
6073 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306074
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006075 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306076 {
6077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6078 FL("already beacon info added to session(%d)"),
6079 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006080 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306081 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006082
6083 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6084
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306085 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006086 {
6087 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306088 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006089 return -EINVAL;
6090 }
6091 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006093 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6095 params->channel, params->channel_type);
6096#else
6097 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6098#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006099#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006100 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6101 params->ssid_len, params->hidden_ssid);
6102 }
6103
6104 EXIT();
6105 return status;
6106}
6107
6108
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306109static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006110 struct net_device *dev,
6111 struct cfg80211_beacon_data *params)
6112{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik10728722014-05-14 16:20:25 +05306114 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306115 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006116
6117 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05306118 if (NULL == pAdapter)
6119 {
6120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6121 "%s: HDD adapter context is Null", __func__);
6122 return -ENODEV;
6123 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306124 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6125 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6126 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006127 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006128 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306129
6130 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6131 status = wlan_hdd_validate_context(pHddCtx);
6132
6133 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006134 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6136 "%s: HDD context is not valid", __func__);
6137 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006138 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006139
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306140 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006141 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306142 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006143 {
6144 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306145
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006146 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306147
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006148 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306149 {
6150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6151 FL("session(%d) beacon data points to NULL"),
6152 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006153 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306154 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006155
6156 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6157
6158 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306159 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006160 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006161 return -EINVAL;
6162 }
6163
6164 pAdapter->sessionCtx.ap.beacon = new;
6165
6166 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6167 }
6168
6169 EXIT();
6170 return status;
6171}
6172
6173#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6174
Jeff Johnson295189b2012-06-20 16:38:30 -07006175
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306176static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 struct net_device *dev,
6178 struct bss_parameters *params)
6179{
6180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6181
6182 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05306183 if (NULL == pAdapter)
6184 {
6185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6186 "%s: HDD adapter context is Null", __func__);
6187 return -ENODEV;
6188 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306189 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6190 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6191 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6193 __func__, hdd_device_modetoString(pAdapter->device_mode),
6194 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006195
6196 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306198 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 {
6200 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6201 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306202 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 {
6204 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 }
6207
6208 EXIT();
6209 return 0;
6210}
6211
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306212static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6213 struct net_device *dev,
6214 struct bss_parameters *params)
6215{
6216 int ret;
6217
6218 vos_ssr_protect(__func__);
6219 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6220 vos_ssr_unprotect(__func__);
6221
6222 return ret;
6223}
Kiet Lam10841362013-11-01 11:36:50 +05306224/* FUNCTION: wlan_hdd_change_country_code_cd
6225* to wait for contry code completion
6226*/
6227void* wlan_hdd_change_country_code_cb(void *pAdapter)
6228{
6229 hdd_adapter_t *call_back_pAdapter = pAdapter;
6230 complete(&call_back_pAdapter->change_country_code);
6231 return NULL;
6232}
6233
Jeff Johnson295189b2012-06-20 16:38:30 -07006234/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306235 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6237 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306238int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 struct net_device *ndev,
6240 enum nl80211_iftype type,
6241 u32 *flags,
6242 struct vif_params *params
6243 )
6244{
6245 struct wireless_dev *wdev;
6246 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006247 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006248 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 tCsrRoamProfile *pRoamProfile = NULL;
6250 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306251 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 eMib_dot11DesiredBssType connectedBssType;
6253 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306254 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006255
6256 ENTER();
6257
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306258 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006259 {
6260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6261 "%s: Adapter context is null", __func__);
6262 return VOS_STATUS_E_FAILURE;
6263 }
6264
6265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6266 if (!pHddCtx)
6267 {
6268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6269 "%s: HDD context is null", __func__);
6270 return VOS_STATUS_E_FAILURE;
6271 }
6272
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306273 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6274 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6275 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306276 status = wlan_hdd_validate_context(pHddCtx);
6277
6278 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6281 "%s: HDD context is not valid", __func__);
6282 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 }
6284
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6286 __func__, hdd_device_modetoString(pAdapter->device_mode),
6287 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006288
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306289 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 wdev = ndev->ieee80211_ptr;
6291
6292#ifdef WLAN_BTAMP_FEATURE
6293 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6294 (NL80211_IFTYPE_ADHOC == type)||
6295 (NL80211_IFTYPE_AP == type)||
6296 (NL80211_IFTYPE_P2P_GO == type))
6297 {
6298 pHddCtx->isAmpAllowed = VOS_FALSE;
6299 // stop AMP traffic
6300 status = WLANBAP_StopAmp();
6301 if(VOS_STATUS_SUCCESS != status )
6302 {
6303 pHddCtx->isAmpAllowed = VOS_TRUE;
6304 hddLog(VOS_TRACE_LEVEL_FATAL,
6305 "%s: Failed to stop AMP", __func__);
6306 return -EINVAL;
6307 }
6308 }
6309#endif //WLAN_BTAMP_FEATURE
6310 /* Reset the current device mode bit mask*/
6311 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6312
6313 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006315 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 )
6317 {
6318 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006319 if (!pWextState)
6320 {
6321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6322 "%s: pWextState is null", __func__);
6323 return VOS_STATUS_E_FAILURE;
6324 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 pRoamProfile = &pWextState->roamProfile;
6326 LastBSSType = pRoamProfile->BSSType;
6327
6328 switch (type)
6329 {
6330 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 hddLog(VOS_TRACE_LEVEL_INFO,
6333 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6334 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006335#ifdef WLAN_FEATURE_11AC
6336 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6337 {
6338 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6339 }
6340#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306341 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006342 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006344 //Check for sub-string p2p to confirm its a p2p interface
6345 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306346 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006347 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6348 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6349 }
6350 else
6351 {
6352 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006354 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306355#ifdef FEATURE_WLAN_TDLS
6356 /* The open adapter for the p2p shall skip initializations in
6357 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6358 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6359 * tdls_init when the change_iface sets the device mode to
6360 * WLAN_HDD_P2P_CLIENT.
6361 */
6362
6363 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6364 {
6365 if (0 != wlan_hdd_tdls_init (pAdapter))
6366 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306367 hddLog(VOS_TRACE_LEVEL_ERROR,
6368 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306369 return -EINVAL;
6370 }
6371 }
6372#endif
6373
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 break;
6375 case NL80211_IFTYPE_ADHOC:
6376 hddLog(VOS_TRACE_LEVEL_INFO,
6377 "%s: setting interface Type to ADHOC", __func__);
6378 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6379 pRoamProfile->phyMode =
6380 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006381 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 wdev->iftype = type;
6383 break;
6384
6385 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 {
6388 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6389 "%s: setting interface Type to %s", __func__,
6390 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6391
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006392 //Cancel any remain on channel for GO mode
6393 if (NL80211_IFTYPE_P2P_GO == type)
6394 {
6395 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6396 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006397 if (NL80211_IFTYPE_AP == type)
6398 {
6399 /* As Loading WLAN Driver one interface being created for p2p device
6400 * address. This will take one HW STA and the max number of clients
6401 * that can connect to softAP will be reduced by one. so while changing
6402 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6403 * interface as it is not required in SoftAP mode.
6404 */
6405
6406 // Get P2P Adapter
6407 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6408
6409 if (pP2pAdapter)
6410 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306411 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006412 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6413 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6414 }
6415 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306416 //Disable IMPS & BMPS for SAP/GO
6417 if(VOS_STATUS_E_FAILURE ==
6418 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6419 {
6420 //Fail to Exit BMPS
6421 VOS_ASSERT(0);
6422 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306423#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006424
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306425 /* A Mutex Lock is introduced while changing the mode to
6426 * protect the concurrent access for the Adapters by TDLS
6427 * module.
6428 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306429 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306430#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306432 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 hdd_deinit_adapter( pHddCtx, pAdapter );
6434 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6436 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306437#ifdef FEATURE_WLAN_TDLS
6438 mutex_unlock(&pHddCtx->tdls_lock);
6439#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006440 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6441 (pConfig->apRandomBssidEnabled))
6442 {
6443 /* To meet Android requirements create a randomized
6444 MAC address of the form 02:1A:11:Fx:xx:xx */
6445 get_random_bytes(&ndev->dev_addr[3], 3);
6446 ndev->dev_addr[0] = 0x02;
6447 ndev->dev_addr[1] = 0x1A;
6448 ndev->dev_addr[2] = 0x11;
6449 ndev->dev_addr[3] |= 0xF0;
6450 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6451 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006452 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6453 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006454 }
6455
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 hdd_set_ap_ops( pAdapter->dev );
6457
Kiet Lam10841362013-11-01 11:36:50 +05306458 /* This is for only SAP mode where users can
6459 * control country through ini.
6460 * P2P GO follows station country code
6461 * acquired during the STA scanning. */
6462 if((NL80211_IFTYPE_AP == type) &&
6463 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6464 {
6465 int status = 0;
6466 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6467 "%s: setting country code from INI ", __func__);
6468 init_completion(&pAdapter->change_country_code);
6469 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6470 (void *)(tSmeChangeCountryCallback)
6471 wlan_hdd_change_country_code_cb,
6472 pConfig->apCntryCode, pAdapter,
6473 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306474 eSIR_FALSE,
6475 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306476 if (eHAL_STATUS_SUCCESS == status)
6477 {
6478 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306479 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306480 &pAdapter->change_country_code,
6481 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306482 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306483 {
6484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306485 FL("SME Timed out while setting country code %ld"),
6486 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006487
6488 if (pHddCtx->isLogpInProgress)
6489 {
6490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6491 "%s: LOGP in Progress. Ignore!!!", __func__);
6492 return -EAGAIN;
6493 }
Kiet Lam10841362013-11-01 11:36:50 +05306494 }
6495 }
6496 else
6497 {
6498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006499 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306500 return -EINVAL;
6501 }
6502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 status = hdd_init_ap_mode(pAdapter);
6504 if(status != VOS_STATUS_SUCCESS)
6505 {
6506 hddLog(VOS_TRACE_LEVEL_FATAL,
6507 "%s: Error initializing the ap mode", __func__);
6508 return -EINVAL;
6509 }
6510 hdd_set_conparam(1);
6511
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 /*interface type changed update in wiphy structure*/
6513 if(wdev)
6514 {
6515 wdev->iftype = type;
6516 pHddCtx->change_iface = type;
6517 }
6518 else
6519 {
6520 hddLog(VOS_TRACE_LEVEL_ERROR,
6521 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6522 return -EINVAL;
6523 }
6524 goto done;
6525 }
6526
6527 default:
6528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6529 __func__);
6530 return -EOPNOTSUPP;
6531 }
6532 }
6533 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006535 )
6536 {
6537 switch(type)
6538 {
6539 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306542#ifdef FEATURE_WLAN_TDLS
6543
6544 /* A Mutex Lock is introduced while changing the mode to
6545 * protect the concurrent access for the Adapters by TDLS
6546 * module.
6547 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306548 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306549#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306550 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006551 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006553 //Check for sub-string p2p to confirm its a p2p interface
6554 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006555 {
6556 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6557 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6558 }
6559 else
6560 {
6561 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 hdd_set_conparam(0);
6565 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6567 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306568#ifdef FEATURE_WLAN_TDLS
6569 mutex_unlock(&pHddCtx->tdls_lock);
6570#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306571 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 if( VOS_STATUS_SUCCESS != status )
6573 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006574 /* In case of JB, for P2P-GO, only change interface will be called,
6575 * This is the right place to enable back bmps_imps()
6576 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306577 if (pHddCtx->hdd_wlan_suspended)
6578 {
6579 hdd_set_pwrparams(pHddCtx);
6580 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006581 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006582 goto done;
6583 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6587 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 goto done;
6589 default:
6590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6591 __func__);
6592 return -EOPNOTSUPP;
6593
6594 }
6595
6596 }
6597 else
6598 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306599 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6600 __func__, hdd_device_modetoString(pAdapter->device_mode),
6601 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006602 return -EOPNOTSUPP;
6603 }
6604
6605
6606 if(pRoamProfile)
6607 {
6608 if ( LastBSSType != pRoamProfile->BSSType )
6609 {
6610 /*interface type changed update in wiphy structure*/
6611 wdev->iftype = type;
6612
6613 /*the BSS mode changed, We need to issue disconnect
6614 if connected or in IBSS disconnect state*/
6615 if ( hdd_connGetConnectedBssType(
6616 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6617 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6618 {
6619 /*need to issue a disconnect to CSR.*/
6620 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6621 if( eHAL_STATUS_SUCCESS ==
6622 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6623 pAdapter->sessionId,
6624 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6625 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306626 ret = wait_for_completion_interruptible_timeout(
6627 &pAdapter->disconnect_comp_var,
6628 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6629 if (ret <= 0)
6630 {
6631 hddLog(VOS_TRACE_LEVEL_ERROR,
6632 FL("wait on disconnect_comp_var failed %ld"), ret);
6633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006634 }
6635 }
6636 }
6637 }
6638
6639done:
6640 /*set bitmask based on updated value*/
6641 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006642
6643 /* Only STA mode support TM now
6644 * all other mode, TM feature should be disabled */
6645 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6646 (~VOS_STA & pHddCtx->concurrency_mode) )
6647 {
6648 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6649 }
6650
Jeff Johnson295189b2012-06-20 16:38:30 -07006651#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306652 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
6654 {
6655 //we are ok to do AMP
6656 pHddCtx->isAmpAllowed = VOS_TRUE;
6657 }
6658#endif //WLAN_BTAMP_FEATURE
6659 EXIT();
6660 return 0;
6661}
6662
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306663/*
6664 * FUNCTION: wlan_hdd_cfg80211_change_iface
6665 * wrapper function to protect the actual implementation from SSR.
6666 */
6667int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6668 struct net_device *ndev,
6669 enum nl80211_iftype type,
6670 u32 *flags,
6671 struct vif_params *params
6672 )
6673{
6674 int ret;
6675
6676 vos_ssr_protect(__func__);
6677 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6678 vos_ssr_unprotect(__func__);
6679
6680 return ret;
6681}
6682
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006683#ifdef FEATURE_WLAN_TDLS
6684static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6685 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6686{
6687 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6688 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6689 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006690 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306691 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306692 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006693
6694 ENTER();
6695
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306696 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006697 {
6698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6699 "Invalid arguments");
6700 return -EINVAL;
6701 }
Hoonki Lee27511902013-03-14 18:19:06 -07006702
6703 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6704 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6705 {
6706 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6707 "%s: TDLS mode is disabled OR not enabled in FW."
6708 MAC_ADDRESS_STR " Request declined.",
6709 __func__, MAC_ADDR_ARRAY(mac));
6710 return -ENOTSUPP;
6711 }
6712
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006713 if (pHddCtx->isLogpInProgress)
6714 {
6715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6716 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006717 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006718 return -EBUSY;
6719 }
6720
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306721 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006722
6723 if ( NULL == pTdlsPeer ) {
6724 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6725 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6726 __func__, MAC_ADDR_ARRAY(mac), update);
6727 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006728 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006729
6730 /* in add station, we accept existing valid staId if there is */
6731 if ((0 == update) &&
6732 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6733 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006734 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006735 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006736 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006737 " link_status %d. staId %d. add station ignored.",
6738 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6739 return 0;
6740 }
6741 /* in change station, we accept only when staId is valid */
6742 if ((1 == update) &&
6743 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6744 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6745 {
6746 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6747 "%s: " MAC_ADDRESS_STR
6748 " link status %d. staId %d. change station %s.",
6749 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6750 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6751 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006752 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006753
6754 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306755 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006756 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6758 "%s: " MAC_ADDRESS_STR
6759 " TDLS setup is ongoing. Request declined.",
6760 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006761 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006762 }
6763
6764 /* first to check if we reached to maximum supported TDLS peer.
6765 TODO: for now, return -EPERM looks working fine,
6766 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306767 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6768 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006769 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6771 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306772 " TDLS Max peer already connected. Request declined."
6773 " Num of peers (%d), Max allowed (%d).",
6774 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6775 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006776 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006777 }
6778 else
6779 {
6780 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306781 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006782 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006783 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6785 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6786 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006787 return -EPERM;
6788 }
6789 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006790 if (0 == update)
6791 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006792
Jeff Johnsond75fe012013-04-06 10:53:06 -07006793 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306794 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006795 {
6796 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6797 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006798 if(StaParams->htcap_present)
6799 {
6800 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6801 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6802 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6803 "ht_capa->extended_capabilities: %0x",
6804 StaParams->HTCap.extendedHtCapInfo);
6805 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006806 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6807 "params->capability: %0x",StaParams->capability);
6808 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006809 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006810 if(StaParams->vhtcap_present)
6811 {
6812 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6813 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6814 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6815 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6816 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006817 {
6818 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006820 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6821 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6822 "[%d]: %x ", i, StaParams->supported_rates[i]);
6823 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006824 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306825 else if ((1 == update) && (NULL == StaParams))
6826 {
6827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6828 "%s : update is true, but staParams is NULL. Error!", __func__);
6829 return -EPERM;
6830 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006831
6832 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6833
6834 if (!update)
6835 {
6836 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6837 pAdapter->sessionId, mac);
6838 }
6839 else
6840 {
6841 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6842 pAdapter->sessionId, mac, StaParams);
6843 }
6844
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306845 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006846 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6847
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306848 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006849 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306851 "%s: timeout waiting for tdls add station indication %ld",
6852 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006853 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006854 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306855
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006856 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6857 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006859 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006860 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006861 }
6862
6863 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006864
6865error:
6866 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6867 return -EPERM;
6868
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006869}
6870#endif
6871
Jeff Johnson295189b2012-06-20 16:38:30 -07006872static int wlan_hdd_change_station(struct wiphy *wiphy,
6873 struct net_device *dev,
6874 u8 *mac,
6875 struct station_parameters *params)
6876{
6877 VOS_STATUS status = VOS_STATUS_SUCCESS;
6878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306879 hdd_context_t *pHddCtx;
6880 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006882#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006883 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006884 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306885 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006886#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006887 ENTER();
6888
Gopichand Nakkala29149562013-05-10 21:43:41 +05306889 if ((NULL == pAdapter))
6890 {
Sushant Kaushik10728722014-05-14 16:20:25 +05306891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306892 "invalid adapter ");
6893 return -EINVAL;
6894 }
6895
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306896 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6897 TRACE_CODE_HDD_CHANGE_STATION,
6898 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306899 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6900 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6901
6902 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6903 {
6904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6905 "invalid HDD state or HDD station context");
6906 return -EINVAL;
6907 }
6908
6909 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006910 {
6911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6912 "%s:LOGP in Progress. Ignore!!!", __func__);
6913 return -EAGAIN;
6914 }
6915
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6917
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006918 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6919 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006921 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306923 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 WLANTL_STA_AUTHENTICATED);
6925
Gopichand Nakkala29149562013-05-10 21:43:41 +05306926 if (status != VOS_STATUS_SUCCESS)
6927 {
6928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6929 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6930 return -EINVAL;
6931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 }
6933 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006934 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6935 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306936#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006937 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6938 StaParams.capability = params->capability;
6939 StaParams.uapsd_queues = params->uapsd_queues;
6940 StaParams.max_sp = params->max_sp;
6941
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306942 /* Convert (first channel , number of channels) tuple to
6943 * the total list of channels. This goes with the assumption
6944 * that if the first channel is < 14, then the next channels
6945 * are an incremental of 1 else an incremental of 4 till the number
6946 * of channels.
6947 */
6948 if (0 != params->supported_channels_len) {
6949 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6950 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6951 {
6952 int wifi_chan_index;
6953 StaParams.supported_channels[j] = params->supported_channels[i];
6954 wifi_chan_index =
6955 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6956 no_of_channels = params->supported_channels[i+1];
6957 for(k=1; k <= no_of_channels; k++)
6958 {
6959 StaParams.supported_channels[j+1] =
6960 StaParams.supported_channels[j] + wifi_chan_index;
6961 j+=1;
6962 }
6963 }
6964 StaParams.supported_channels_len = j;
6965 }
6966 vos_mem_copy(StaParams.supported_oper_classes,
6967 params->supported_oper_classes,
6968 params->supported_oper_classes_len);
6969 StaParams.supported_oper_classes_len =
6970 params->supported_oper_classes_len;
6971
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006972 if (0 != params->ext_capab_len)
6973 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
6974 sizeof(StaParams.extn_capability));
6975
6976 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006977 {
6978 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006979 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006980 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006981
6982 StaParams.supported_rates_len = params->supported_rates_len;
6983
6984 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
6985 * The supported_rates array , for all the structures propogating till Add Sta
6986 * to the firmware has to be modified , if the supplicant (ieee80211) is
6987 * modified to send more rates.
6988 */
6989
6990 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
6991 */
6992 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
6993 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
6994
6995 if (0 != StaParams.supported_rates_len) {
6996 int i = 0;
6997 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
6998 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007000 "Supported Rates with Length %d", StaParams.supported_rates_len);
7001 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007003 "[%d]: %0x", i, StaParams.supported_rates[i]);
7004 }
7005
7006 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007007 {
7008 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007009 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007010 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007011
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007012 if (0 != params->ext_capab_len ) {
7013 /*Define A Macro : TODO Sunil*/
7014 if ((1<<4) & StaParams.extn_capability[3]) {
7015 isBufSta = 1;
7016 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307017 /* TDLS Channel Switching Support */
7018 if ((1<<6) & StaParams.extn_capability[3]) {
7019 isOffChannelSupported = 1;
7020 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007021 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307022 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7023 &StaParams, isBufSta,
7024 isOffChannelSupported);
7025
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307026 if (VOS_STATUS_SUCCESS != status) {
7027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7028 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7029 return -EINVAL;
7030 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007031 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7032
7033 if (VOS_STATUS_SUCCESS != status) {
7034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7035 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7036 return -EINVAL;
7037 }
7038 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007039#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307040 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007041 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 return status;
7043}
7044
7045/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307046 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 * This function is used to initialize the key information
7048 */
7049#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307050static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 struct net_device *ndev,
7052 u8 key_index, bool pairwise,
7053 const u8 *mac_addr,
7054 struct key_params *params
7055 )
7056#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307057static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 struct net_device *ndev,
7059 u8 key_index, const u8 *mac_addr,
7060 struct key_params *params
7061 )
7062#endif
7063{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 tCsrRoamSetKey setKey;
7066 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307067 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007068 v_U32_t roamId= 0xFF;
7069 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007070 hdd_hostapd_state_t *pHostapdState;
7071 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007072 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307073 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007074
7075 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05307076 if (NULL == pAdapter)
7077 {
7078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7079 "%s: HDD adapter context is Null", __func__);
7080 return -ENODEV;
7081 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7083 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7084 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307085 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7086 status = wlan_hdd_validate_context(pHddCtx);
7087
7088 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007089 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7091 "%s: HDD context is not valid", __func__);
7092 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007093 }
7094
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7096 __func__, hdd_device_modetoString(pAdapter->device_mode),
7097 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007098
7099 if (CSR_MAX_NUM_KEY <= key_index)
7100 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007102 key_index);
7103
7104 return -EINVAL;
7105 }
7106
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007107 if (CSR_MAX_KEY_LEN < params->key_len)
7108 {
7109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7110 params->key_len);
7111
7112 return -EINVAL;
7113 }
7114
7115 hddLog(VOS_TRACE_LEVEL_INFO,
7116 "%s: called with key index = %d & key length %d",
7117 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007118
7119 /*extract key idx, key len and key*/
7120 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7121 setKey.keyId = key_index;
7122 setKey.keyLength = params->key_len;
7123 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7124
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007125 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 {
7127 case WLAN_CIPHER_SUITE_WEP40:
7128 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7129 break;
7130
7131 case WLAN_CIPHER_SUITE_WEP104:
7132 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7133 break;
7134
7135 case WLAN_CIPHER_SUITE_TKIP:
7136 {
7137 u8 *pKey = &setKey.Key[0];
7138 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7139
7140 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7141
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007142 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
7144 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007145 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 |--------------|----------|----------|
7147 <---16bytes---><--8bytes--><--8bytes-->
7148
7149 */
7150 /*Sme expects the 32 bytes key to be in the below order
7151
7152 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007153 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 |--------------|----------|----------|
7155 <---16bytes---><--8bytes--><--8bytes-->
7156 */
7157 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007158 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007159
7160 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007161 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007162
7163 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007164 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007165
7166
7167 break;
7168 }
7169
7170 case WLAN_CIPHER_SUITE_CCMP:
7171 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7172 break;
7173
7174#ifdef FEATURE_WLAN_WAPI
7175 case WLAN_CIPHER_SUITE_SMS4:
7176 {
7177 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7178 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7179 params->key, params->key_len);
7180 return 0;
7181 }
7182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007183
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007184#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007185 case WLAN_CIPHER_SUITE_KRK:
7186 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7187 break;
7188#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007189
7190#ifdef WLAN_FEATURE_11W
7191 case WLAN_CIPHER_SUITE_AES_CMAC:
7192 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007193 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007194#endif
7195
Jeff Johnson295189b2012-06-20 16:38:30 -07007196 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 __func__, params->cipher);
7199 return -EOPNOTSUPP;
7200 }
7201
7202 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7203 __func__, setKey.encType);
7204
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007205 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7207 (!pairwise)
7208#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007209 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007210#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007211 )
7212 {
7213 /* set group key*/
7214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7215 "%s- %d: setting Broadcast key",
7216 __func__, __LINE__);
7217 setKey.keyDirection = eSIR_RX_ONLY;
7218 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7219 }
7220 else
7221 {
7222 /* set pairwise key*/
7223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7224 "%s- %d: setting pairwise key",
7225 __func__, __LINE__);
7226 setKey.keyDirection = eSIR_TX_RX;
7227 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7228 }
7229 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7230 {
7231 setKey.keyDirection = eSIR_TX_RX;
7232 /*Set the group key*/
7233 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7234 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007235
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007236 if ( 0 != status )
7237 {
7238 hddLog(VOS_TRACE_LEVEL_ERROR,
7239 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7240 return -EINVAL;
7241 }
7242 /*Save the keys here and call sme_RoamSetKey for setting
7243 the PTK after peer joins the IBSS network*/
7244 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7245 &setKey, sizeof(tCsrRoamSetKey));
7246 return status;
7247 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307248 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7249 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7250 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007252 if( pHostapdState->bssState == BSS_START )
7253 {
c_hpothu7c55da62014-01-23 18:34:02 +05307254 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7255 vos_status = wlan_hdd_check_ula_done(pAdapter);
7256
7257 if ( vos_status != VOS_STATUS_SUCCESS )
7258 {
7259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7260 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7261 __LINE__, vos_status );
7262
7263 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7264
7265 return -EINVAL;
7266 }
7267
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7269
7270 if ( status != eHAL_STATUS_SUCCESS )
7271 {
7272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7273 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7274 __LINE__, status );
7275 }
7276 }
7277
7278 /* Saving WEP keys */
7279 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7280 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7281 {
7282 //Save the wep key in ap context. Issue setkey after the BSS is started.
7283 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7284 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7285 }
7286 else
7287 {
7288 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007289 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7291 }
7292 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007293 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7294 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 {
7296 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7297 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7298
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7300 if (!pairwise)
7301#else
7302 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7303#endif
7304 {
7305 /* set group key*/
7306 if (pHddStaCtx->roam_info.deferKeyComplete)
7307 {
7308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7309 "%s- %d: Perform Set key Complete",
7310 __func__, __LINE__);
7311 hdd_PerformRoamSetKeyComplete(pAdapter);
7312 }
7313 }
7314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7316
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007317 pWextState->roamProfile.Keys.defaultIndex = key_index;
7318
7319
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007320 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 params->key, params->key_len);
7322
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307323
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7325
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307326 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307328 __func__, setKey.peerMac[0], setKey.peerMac[1],
7329 setKey.peerMac[2], setKey.peerMac[3],
7330 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 setKey.keyDirection);
7332
7333 vos_status = wlan_hdd_check_ula_done(pAdapter);
7334
7335 if ( vos_status != VOS_STATUS_SUCCESS )
7336 {
7337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7338 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7339 __LINE__, vos_status );
7340
7341 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7342
7343 return -EINVAL;
7344
7345 }
7346
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007347#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307348 /* The supplicant may attempt to set the PTK once pre-authentication
7349 is done. Save the key in the UMAC and include it in the ADD BSS
7350 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007351 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307352 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007353 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307354 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7355 "%s: Update PreAuth Key success", __func__);
7356 return 0;
7357 }
7358 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7359 {
7360 hddLog(VOS_TRACE_LEVEL_ERROR,
7361 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307362 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007363 }
7364#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007365
7366 /* issue set key request to SME*/
7367 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7368 pAdapter->sessionId, &setKey, &roamId );
7369
7370 if ( 0 != status )
7371 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307372 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7374 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7375 return -EINVAL;
7376 }
7377
7378
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307379 /* in case of IBSS as there was no information available about WEP keys during
7380 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307382 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7383 !( ( IW_AUTH_KEY_MGMT_802_1X
7384 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7386 )
7387 &&
7388 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7389 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7390 )
7391 )
7392 {
7393 setKey.keyDirection = eSIR_RX_ONLY;
7394 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7395
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307396 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307398 __func__, setKey.peerMac[0], setKey.peerMac[1],
7399 setKey.peerMac[2], setKey.peerMac[3],
7400 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007401 setKey.keyDirection);
7402
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307403 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 pAdapter->sessionId, &setKey, &roamId );
7405
7406 if ( 0 != status )
7407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307408 hddLog(VOS_TRACE_LEVEL_ERROR,
7409 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 __func__, status);
7411 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7412 return -EINVAL;
7413 }
7414 }
7415 }
7416
7417 return 0;
7418}
7419
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7421static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7422 struct net_device *ndev,
7423 u8 key_index, bool pairwise,
7424 const u8 *mac_addr,
7425 struct key_params *params
7426 )
7427#else
7428static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7429 struct net_device *ndev,
7430 u8 key_index, const u8 *mac_addr,
7431 struct key_params *params
7432 )
7433#endif
7434{
7435 int ret;
7436 vos_ssr_protect(__func__);
7437#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7438 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7439 mac_addr, params);
7440#else
7441 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7442 params);
7443#endif
7444 vos_ssr_unprotect(__func__);
7445
7446 return ret;
7447}
7448
Jeff Johnson295189b2012-06-20 16:38:30 -07007449/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307450 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 * This function is used to get the key information
7452 */
7453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307454static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307455 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307457 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 const u8 *mac_addr, void *cookie,
7459 void (*callback)(void *cookie, struct key_params*)
7460 )
7461#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307462static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307463 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 struct net_device *ndev,
7465 u8 key_index, const u8 *mac_addr, void *cookie,
7466 void (*callback)(void *cookie, struct key_params*)
7467 )
7468#endif
7469{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Sushant Kaushik10728722014-05-14 16:20:25 +05307471 hdd_wext_state_t *pWextState= NULL;
7472 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 struct key_params params;
7474
7475 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307476
Sushant Kaushik10728722014-05-14 16:20:25 +05307477 if (NULL == pAdapter)
7478 {
7479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7480 "%s: HDD adapter context is Null", __func__);
7481 return -ENODEV;
7482 }
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307483 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7484 __func__, hdd_device_modetoString(pAdapter->device_mode),
7485 pAdapter->device_mode);
Sushant Kaushik10728722014-05-14 16:20:25 +05307486 pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7487 pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007488 memset(&params, 0, sizeof(params));
7489
7490 if (CSR_MAX_NUM_KEY <= key_index)
7491 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007495
7496 switch(pRoamProfile->EncryptionType.encryptionType[0])
7497 {
7498 case eCSR_ENCRYPT_TYPE_NONE:
7499 params.cipher = IW_AUTH_CIPHER_NONE;
7500 break;
7501
7502 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7503 case eCSR_ENCRYPT_TYPE_WEP40:
7504 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7505 break;
7506
7507 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7508 case eCSR_ENCRYPT_TYPE_WEP104:
7509 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7510 break;
7511
7512 case eCSR_ENCRYPT_TYPE_TKIP:
7513 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7514 break;
7515
7516 case eCSR_ENCRYPT_TYPE_AES:
7517 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7518 break;
7519
7520 default:
7521 params.cipher = IW_AUTH_CIPHER_NONE;
7522 break;
7523 }
c_hpothuaaf19692014-05-17 17:01:48 +05307524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7525 TRACE_CODE_HDD_CFG80211_GET_KEY,
7526 pAdapter->sessionId, params.cipher));
Jeff Johnson295189b2012-06-20 16:38:30 -07007527 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7528 params.seq_len = 0;
7529 params.seq = NULL;
7530 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7531 callback(cookie, &params);
7532 return 0;
7533}
7534
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307535#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7536static int wlan_hdd_cfg80211_get_key(
7537 struct wiphy *wiphy,
7538 struct net_device *ndev,
7539 u8 key_index, bool pairwise,
7540 const u8 *mac_addr, void *cookie,
7541 void (*callback)(void *cookie, struct key_params*)
7542 )
7543#else
7544static int wlan_hdd_cfg80211_get_key(
7545 struct wiphy *wiphy,
7546 struct net_device *ndev,
7547 u8 key_index, const u8 *mac_addr, void *cookie,
7548 void (*callback)(void *cookie, struct key_params*)
7549 )
7550#endif
7551{
7552 int ret;
7553
7554 vos_ssr_protect(__func__);
7555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7556 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7557 mac_addr, cookie, callback);
7558#else
7559 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7560 callback);
7561#endif
7562 vos_ssr_unprotect(__func__);
7563
7564 return ret;
7565}
7566
Jeff Johnson295189b2012-06-20 16:38:30 -07007567/*
7568 * FUNCTION: wlan_hdd_cfg80211_del_key
7569 * This function is used to delete the key information
7570 */
7571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307572static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307574 u8 key_index,
7575 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 const u8 *mac_addr
7577 )
7578#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307579static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 struct net_device *ndev,
7581 u8 key_index,
7582 const u8 *mac_addr
7583 )
7584#endif
7585{
7586 int status = 0;
7587
7588 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307589 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007590 //it is observed that this is invalidating peer
7591 //key index whenever re-key is done. This is affecting data link.
7592 //It should be ok to ignore del_key.
7593#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307594 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7595 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7597 tCsrRoamSetKey setKey;
7598 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307599
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 ENTER();
7601
7602 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7603 __func__,pAdapter->device_mode);
7604
7605 if (CSR_MAX_NUM_KEY <= key_index)
7606 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007608 key_index);
7609
7610 return -EINVAL;
7611 }
7612
7613 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7614 setKey.keyId = key_index;
7615
7616 if (mac_addr)
7617 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7618 else
7619 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7620
7621 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7622
7623 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307625 )
7626 {
7627
7628 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7630 if( pHostapdState->bssState == BSS_START)
7631 {
7632 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307633
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 if ( status != eHAL_STATUS_SUCCESS )
7635 {
7636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7637 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7638 __LINE__, status );
7639 }
7640 }
7641 }
7642 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307643 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 )
7645 {
7646 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7647
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307648 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7649
7650 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307652 __func__, setKey.peerMac[0], setKey.peerMac[1],
7653 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007654 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307655 if(pAdapter->sessionCtx.station.conn_info.connState ==
7656 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307658 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307660
Jeff Johnson295189b2012-06-20 16:38:30 -07007661 if ( 0 != status )
7662 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307663 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 "%s: sme_RoamSetKey failure, returned %d",
7665 __func__, status);
7666 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7667 return -EINVAL;
7668 }
7669 }
7670 }
7671#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007672 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 return status;
7674}
7675
7676/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307677 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007678 * This function is used to set the default tx key index
7679 */
7680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307681static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007682 struct net_device *ndev,
7683 u8 key_index,
7684 bool unicast, bool multicast)
7685#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307686static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 struct net_device *ndev,
7688 u8 key_index)
7689#endif
7690{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307691 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307692 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307693 hdd_wext_state_t *pWextState;
7694 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307695 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007696
7697 ENTER();
7698
Gopichand Nakkala29149562013-05-10 21:43:41 +05307699 if ((NULL == pAdapter))
7700 {
Sushant Kaushik10728722014-05-14 16:20:25 +05307701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307702 "invalid adapter");
7703 return -EINVAL;
7704 }
7705
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7707 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7708 pAdapter->sessionId, key_index));
7709
Gopichand Nakkala29149562013-05-10 21:43:41 +05307710 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7711 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7712
7713 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7714 {
7715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7716 "invalid Wext state or HDD context");
7717 return -EINVAL;
7718 }
7719
Arif Hussain6d2a3322013-11-17 19:50:10 -08007720 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307722
Jeff Johnson295189b2012-06-20 16:38:30 -07007723 if (CSR_MAX_NUM_KEY <= key_index)
7724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 key_index);
7727
7728 return -EINVAL;
7729 }
7730
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307731 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7732 status = wlan_hdd_validate_context(pHddCtx);
7733
7734 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7737 "%s: HDD context is not valid", __func__);
7738 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007739 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307740
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307743 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307745 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007746 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307747 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007748 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007749 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307750 {
7751 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007752 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307753
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 tCsrRoamSetKey setKey;
7755 v_U32_t roamId= 0xFF;
7756 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307757
7758 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307760
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 Keys->defaultIndex = (u8)key_index;
7762 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7763 setKey.keyId = key_index;
7764 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307765
7766 vos_mem_copy(&setKey.Key[0],
7767 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307769
Gopichand Nakkala29149562013-05-10 21:43:41 +05307770 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771
7772 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 &pHddStaCtx->conn_info.bssId[0],
7774 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307775
Gopichand Nakkala29149562013-05-10 21:43:41 +05307776 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7777 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7778 eCSR_ENCRYPT_TYPE_WEP104)
7779 {
7780 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7781 even though ap is configured for WEP-40 encryption. In this canse the key length
7782 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7783 type(104) and switching encryption type to 40*/
7784 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7785 eCSR_ENCRYPT_TYPE_WEP40;
7786 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7787 eCSR_ENCRYPT_TYPE_WEP40;
7788 }
7789
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307790 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307794 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307796
Jeff Johnson295189b2012-06-20 16:38:30 -07007797 if ( 0 != status )
7798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307799 hddLog(VOS_TRACE_LEVEL_ERROR,
7800 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 status);
7802 return -EINVAL;
7803 }
7804 }
7805 }
7806
7807 /* In SoftAp mode setting key direction for default mode */
7808 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7809 {
7810 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7811 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7812 (eCSR_ENCRYPT_TYPE_AES !=
7813 pWextState->roamProfile.EncryptionType.encryptionType[0])
7814 )
7815 {
7816 /* Saving key direction for default key index to TX default */
7817 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7818 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7819 }
7820 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307821
Jeff Johnson295189b2012-06-20 16:38:30 -07007822 return status;
7823}
7824
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7826static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7827 struct net_device *ndev,
7828 u8 key_index,
7829 bool unicast, bool multicast)
7830#else
7831static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7832 struct net_device *ndev,
7833 u8 key_index)
7834#endif
7835{
7836 int ret;
7837 vos_ssr_protect(__func__);
7838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7839 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7840 multicast);
7841#else
7842 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7843#endif
7844 vos_ssr_unprotect(__func__);
7845
7846 return ret;
7847}
7848
Jeff Johnson295189b2012-06-20 16:38:30 -07007849/*
7850 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7851 * This function is used to inform the BSS details to nl80211 interface.
7852 */
7853static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7854 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7855{
7856 struct net_device *dev = pAdapter->dev;
7857 struct wireless_dev *wdev = dev->ieee80211_ptr;
7858 struct wiphy *wiphy = wdev->wiphy;
7859 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7860 int chan_no;
7861 int ie_length;
7862 const char *ie;
7863 unsigned int freq;
7864 struct ieee80211_channel *chan;
7865 int rssi = 0;
7866 struct cfg80211_bss *bss = NULL;
7867
7868 ENTER();
7869
7870 if( NULL == pBssDesc )
7871 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007872 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 return bss;
7874 }
7875
7876 chan_no = pBssDesc->channelId;
7877 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7878 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7879
7880 if( NULL == ie )
7881 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007882 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007883 return bss;
7884 }
7885
7886#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7887 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7888 {
7889 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7890 }
7891 else
7892 {
7893 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7894 }
7895#else
7896 freq = ieee80211_channel_to_frequency(chan_no);
7897#endif
7898
7899 chan = __ieee80211_get_channel(wiphy, freq);
7900
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307901 if (!chan) {
7902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7903 return NULL;
7904 }
7905
Abhishek Singhaee43942014-06-16 18:55:47 +05307906 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007907
Abhishek Singhaee43942014-06-16 18:55:47 +05307908 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307909 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 pBssDesc->capabilityInfo,
7911 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307912 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007913}
7914
7915
7916
7917/*
7918 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7919 * This function is used to inform the BSS details to nl80211 interface.
7920 */
7921struct cfg80211_bss*
7922wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7923 tSirBssDescription *bss_desc
7924 )
7925{
7926 /*
7927 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7928 already exists in bss data base of cfg80211 for that particular BSS ID.
7929 Using cfg80211_inform_bss_frame to update the bss entry instead of
7930 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7931 now there is no possibility to get the mgmt(probe response) frame from PE,
7932 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7933 cfg80211_inform_bss_frame.
7934 */
7935 struct net_device *dev = pAdapter->dev;
7936 struct wireless_dev *wdev = dev->ieee80211_ptr;
7937 struct wiphy *wiphy = wdev->wiphy;
7938 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007939#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7940 qcom_ie_age *qie_age = NULL;
7941 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7942#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007944#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 const char *ie =
7946 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7947 unsigned int freq;
7948 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307949 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 struct cfg80211_bss *bss_status = NULL;
7951 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7952 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007953 hdd_context_t *pHddCtx;
7954 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007955#ifdef WLAN_OPEN_SOURCE
7956 struct timespec ts;
7957#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007958
Wilson Yangf80a0542013-10-07 13:02:37 -07007959 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7960 status = wlan_hdd_validate_context(pHddCtx);
7961
7962 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307963 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007964 {
7965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7966 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
7967 return NULL;
7968 }
7969
7970
7971 if (0 != status)
7972 {
7973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7974 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007975 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07007976 }
7977
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307978 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07007979 if (!mgmt)
7980 {
7981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7982 "%s: memory allocation failed ", __func__);
7983 return NULL;
7984 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007985
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07007987
7988#ifdef WLAN_OPEN_SOURCE
7989 /* Android does not want the timestamp from the frame.
7990 Instead it wants a monotonic increasing value */
7991 get_monotonic_boottime(&ts);
7992 mgmt->u.probe_resp.timestamp =
7993 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
7994#else
7995 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
7997 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07007998
7999#endif
8000
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8002 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008003
8004#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8005 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8006 /* Assuming this is the last IE, copy at the end */
8007 ie_length -=sizeof(qcom_ie_age);
8008 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8009 qie_age->element_id = QCOM_VENDOR_IE_ID;
8010 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8011 qie_age->oui_1 = QCOM_OUI1;
8012 qie_age->oui_2 = QCOM_OUI2;
8013 qie_age->oui_3 = QCOM_OUI3;
8014 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8015 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8016#endif
8017
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308019 if (bss_desc->fProbeRsp)
8020 {
8021 mgmt->frame_control |=
8022 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8023 }
8024 else
8025 {
8026 mgmt->frame_control |=
8027 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8028 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008029
8030#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308031 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008032 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8033 {
8034 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8035 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308036 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8038
8039 {
8040 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8041 }
8042 else
8043 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8045 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 kfree(mgmt);
8047 return NULL;
8048 }
8049#else
8050 freq = ieee80211_channel_to_frequency(chan_no);
8051#endif
8052 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008053 /*when the band is changed on the fly using the GUI, three things are done
8054 * 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)
8055 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8056 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8057 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8058 * and discards the channels correponding to previous band and calls back with zero bss results.
8059 * 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
8060 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8061 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8062 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8063 * So drop the bss and continue to next bss.
8064 */
8065 if(chan == NULL)
8066 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008068 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008069 return NULL;
8070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308072 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 * */
8074 if (( eConnectionState_Associated ==
8075 pAdapter->sessionCtx.station.conn_info.connState ) &&
8076 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8077 pAdapter->sessionCtx.station.conn_info.bssId,
8078 WNI_CFG_BSSID_LEN)))
8079 {
8080 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8081 rssi = (pAdapter->rssi * 100);
8082 }
8083 else
8084 {
8085 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8086 }
8087
Nirav Shah20ac06f2013-12-12 18:14:06 +05308088 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8089 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8090 chan->center_freq, (int)(rssi/100));
8091
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8093 frame_len, rssi, GFP_KERNEL);
8094 kfree(mgmt);
8095 return bss_status;
8096}
8097
8098/*
8099 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8100 * This function is used to update the BSS data base of CFG8011
8101 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308102struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 tCsrRoamInfo *pRoamInfo
8104 )
8105{
8106 tCsrRoamConnectedProfile roamProfile;
8107 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8108 struct cfg80211_bss *bss = NULL;
8109
8110 ENTER();
8111
8112 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8113 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8114
8115 if (NULL != roamProfile.pBssDesc)
8116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308117 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 &roamProfile);
8119
8120 if (NULL == bss)
8121 {
8122 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8123 __func__);
8124 }
8125
8126 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8127 }
8128 else
8129 {
8130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8131 __func__);
8132 }
8133 return bss;
8134}
8135
8136/*
8137 * FUNCTION: wlan_hdd_cfg80211_update_bss
8138 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308139static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8140 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308142{
Sushant Kaushik10728722014-05-14 16:20:25 +05308143 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008144 tCsrScanResultInfo *pScanResult;
8145 eHalStatus status = 0;
8146 tScanResultHandle pResult;
8147 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008148 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008149
8150 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05308151 if (NULL == pAdapter)
8152 {
8153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8154 "%s: HDD adapter context is Null", __func__);
8155 return -ENODEV;
8156 }
8157 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308158 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8159 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8160 NO_SESSION, pAdapter->sessionId));
8161
Wilson Yangf80a0542013-10-07 13:02:37 -07008162 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8163
8164 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8167 "%s:LOGP in Progress. Ignore!!!",__func__);
8168 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 }
8170
Wilson Yangf80a0542013-10-07 13:02:37 -07008171
8172 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308173 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008174 {
8175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8176 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8177 return VOS_STATUS_E_PERM;
8178 }
8179
8180
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 /*
8182 * start getting scan results and populate cgf80211 BSS database
8183 */
8184 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8185
8186 /* no scan results */
8187 if (NULL == pResult)
8188 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8190 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 return status;
8192 }
8193
8194 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8195
8196 while (pScanResult)
8197 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308198 /*
8199 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8200 * entry already exists in bss data base of cfg80211 for that
8201 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8202 * bss entry instead of cfg80211_inform_bss, But this call expects
8203 * mgmt packet as input. As of now there is no possibility to get
8204 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 * ieee80211_mgmt(probe response) and passing to c
8206 * fg80211_inform_bss_frame.
8207 * */
8208
8209 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8210 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308211
Jeff Johnson295189b2012-06-20 16:38:30 -07008212
8213 if (NULL == bss_status)
8214 {
8215 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008216 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 }
8218 else
8219 {
Yue Maf49ba872013-08-19 12:04:25 -07008220 cfg80211_put_bss(
8221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8222 wiphy,
8223#endif
8224 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 }
8226
8227 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8228 }
8229
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308230 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008231
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308232 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008233}
8234
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008235void
8236hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8237{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008239 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008240} /****** end hddPrintMacAddr() ******/
8241
8242void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008243hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008244{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308245 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008246 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008247 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8248 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8249 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008250} /****** end hddPrintPmkId() ******/
8251
8252//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8253//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8254
8255//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8256//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8257
8258#define dump_bssid(bssid) \
8259 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008260 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8261 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008262 }
8263
8264#define dump_pmkid(pMac, pmkid) \
8265 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008266 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8267 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008268 }
8269
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008270#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008271/*
8272 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8273 * This function is used to notify the supplicant of a new PMKSA candidate.
8274 */
8275int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308276 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008277 int index, bool preauth )
8278{
Jeff Johnsone7245742012-09-05 17:12:55 -07008279#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008280 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008281 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008282
8283 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008284 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008285
8286 if( NULL == pRoamInfo )
8287 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008288 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008289 return -EINVAL;
8290 }
8291
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008292 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8293 {
8294 dump_bssid(pRoamInfo->bssid);
8295 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008296 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008297 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008298#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308299 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008300}
8301#endif //FEATURE_WLAN_LFR
8302
Yue Maef608272013-04-08 23:09:17 -07008303#ifdef FEATURE_WLAN_LFR_METRICS
8304/*
8305 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8306 * 802.11r/LFR metrics reporting function to report preauth initiation
8307 *
8308 */
8309#define MAX_LFR_METRICS_EVENT_LENGTH 100
8310VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8311 tCsrRoamInfo *pRoamInfo)
8312{
8313 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8314 union iwreq_data wrqu;
8315
8316 ENTER();
8317
8318 if (NULL == pAdapter)
8319 {
8320 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8321 return VOS_STATUS_E_FAILURE;
8322 }
8323
8324 /* create the event */
8325 memset(&wrqu, 0, sizeof(wrqu));
8326 memset(metrics_notification, 0, sizeof(metrics_notification));
8327
8328 wrqu.data.pointer = metrics_notification;
8329 wrqu.data.length = scnprintf(metrics_notification,
8330 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8331 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8332
8333 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8334
8335 EXIT();
8336
8337 return VOS_STATUS_SUCCESS;
8338}
8339
8340/*
8341 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8342 * 802.11r/LFR metrics reporting function to report preauth completion
8343 * or failure
8344 */
8345VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8346 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8347{
8348 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8349 union iwreq_data wrqu;
8350
8351 ENTER();
8352
8353 if (NULL == pAdapter)
8354 {
8355 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8356 return VOS_STATUS_E_FAILURE;
8357 }
8358
8359 /* create the event */
8360 memset(&wrqu, 0, sizeof(wrqu));
8361 memset(metrics_notification, 0, sizeof(metrics_notification));
8362
8363 scnprintf(metrics_notification, sizeof(metrics_notification),
8364 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8365 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8366
8367 if (1 == preauth_status)
8368 strncat(metrics_notification, " TRUE", 5);
8369 else
8370 strncat(metrics_notification, " FALSE", 6);
8371
8372 wrqu.data.pointer = metrics_notification;
8373 wrqu.data.length = strlen(metrics_notification);
8374
8375 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8376
8377 EXIT();
8378
8379 return VOS_STATUS_SUCCESS;
8380}
8381
8382/*
8383 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8384 * 802.11r/LFR metrics reporting function to report handover initiation
8385 *
8386 */
8387VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8388 tCsrRoamInfo *pRoamInfo)
8389{
8390 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8391 union iwreq_data wrqu;
8392
8393 ENTER();
8394
8395 if (NULL == pAdapter)
8396 {
8397 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8398 return VOS_STATUS_E_FAILURE;
8399 }
8400
8401 /* create the event */
8402 memset(&wrqu, 0, sizeof(wrqu));
8403 memset(metrics_notification, 0, sizeof(metrics_notification));
8404
8405 wrqu.data.pointer = metrics_notification;
8406 wrqu.data.length = scnprintf(metrics_notification,
8407 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8408 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8409
8410 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8411
8412 EXIT();
8413
8414 return VOS_STATUS_SUCCESS;
8415}
8416#endif
8417
Jeff Johnson295189b2012-06-20 16:38:30 -07008418/*
8419 * FUNCTION: hdd_cfg80211_scan_done_callback
8420 * scanning callback function, called after finishing scan
8421 *
8422 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308423static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8425{
8426 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308427 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008429 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8430 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 struct cfg80211_scan_request *req = NULL;
8432 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308433 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308434 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
8436 ENTER();
8437
8438 hddLog(VOS_TRACE_LEVEL_INFO,
8439 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008440 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 __func__, halHandle, pContext, (int) scanId, (int) status);
8442
Kiet Lamac06e2c2013-10-23 16:25:07 +05308443 pScanInfo->mScanPendingCounter = 0;
8444
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308446 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 &pScanInfo->scan_req_completion_event,
8448 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308449 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308451 hddLog(VOS_TRACE_LEVEL_ERROR,
8452 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008454 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 }
8456
Yue Maef608272013-04-08 23:09:17 -07008457 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 {
8459 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008460 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 }
8462
8463 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308464 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 {
8466 hddLog(VOS_TRACE_LEVEL_INFO,
8467 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008468 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 (int) scanId);
8470 }
8471
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 pAdapter);
8474
8475 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308476 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008477
8478
8479 /* If any client wait scan result through WEXT
8480 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008481 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 {
8483 /* The other scan request waiting for current scan finish
8484 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008485 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008487 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 }
8489 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008490 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008491 {
8492 struct net_device *dev = pAdapter->dev;
8493 union iwreq_data wrqu;
8494 int we_event;
8495 char *msg;
8496
8497 memset(&wrqu, '\0', sizeof(wrqu));
8498 we_event = SIOCGIWSCAN;
8499 msg = NULL;
8500 wireless_send_event(dev, we_event, &wrqu, msg);
8501 }
8502 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008503 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008504
8505 /* Get the Scan Req */
8506 req = pAdapter->request;
8507
8508 if (!req)
8509 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008510 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008511 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008512 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 }
8514
8515 /*
8516 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308517 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 req->n_ssids = 0;
8519 req->n_channels = 0;
8520 req->ie = 0;
8521
Jeff Johnson295189b2012-06-20 16:38:30 -07008522 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008523 /* Scan is no longer pending */
8524 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008525
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008526 /*
8527 * cfg80211_scan_done informing NL80211 about completion
8528 * of scanning
8529 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308530 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8531 {
8532 aborted = true;
8533 }
8534 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008535 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008536
Jeff Johnsone7245742012-09-05 17:12:55 -07008537allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008538 /* release the wake lock at the end of the scan*/
8539 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008540
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008541 /* Acquire wakelock to handle the case where APP's tries to suspend
8542 * immediatly after the driver gets connect request(i.e after scan)
8543 * from supplicant, this result in app's is suspending and not able
8544 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308545 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008546
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008547#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308548 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8549 {
8550 wlan_hdd_tdls_scan_done_callback(pAdapter);
8551 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008552#endif
8553
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 EXIT();
8555 return 0;
8556}
8557
8558/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308559 * FUNCTION: hdd_isConnectionInProgress
8560 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008561 *
8562 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308563v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008564{
8565 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8566 hdd_station_ctx_t *pHddStaCtx = NULL;
8567 hdd_adapter_t *pAdapter = NULL;
8568 VOS_STATUS status = 0;
8569 v_U8_t staId = 0;
8570 v_U8_t *staMac = NULL;
8571
c_hpothu9b781ba2013-12-30 20:57:45 +05308572 if (TRUE == pHddCtx->btCoexModeSet)
8573 {
8574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308575 FL("BTCoex Mode operation in progress"));
8576 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308577 }
8578
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008579 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8580
8581 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8582 {
8583 pAdapter = pAdapterNode->pAdapter;
8584
8585 if( pAdapter )
8586 {
8587 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308588 "%s: Adapter with device mode %s (%d) exists",
8589 __func__, hdd_device_modetoString(pAdapter->device_mode),
8590 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308591 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8592 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8593 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8594 (eConnectionState_Connecting ==
8595 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8596 {
8597 hddLog(VOS_TRACE_LEVEL_ERROR,
8598 "%s: %p(%d) Connection is in progress", __func__,
8599 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8600 return VOS_TRUE;
8601 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008602 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308603 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8604 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008605 {
8606 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8607 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308608 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008609 {
8610 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8611 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008612 "%s: client " MAC_ADDRESS_STR
8613 " is in the middle of WPS/EAPOL exchange.", __func__,
8614 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308615 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008616 }
8617 }
8618 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8619 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8620 {
8621 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8622 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308623 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008624 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8625 {
8626 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8627
8628 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008629 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8630 "middle of WPS/EAPOL exchange.", __func__,
8631 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308632 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008633 }
8634 }
8635 }
8636 }
8637 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8638 pAdapterNode = pNext;
8639 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308640 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308641}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008642
8643/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308644 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008645 * this scan respond to scan trigger and update cfg80211 scan database
8646 * later, scan dump command can be used to recieve scan results
8647 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308648int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008649#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8650 struct net_device *dev,
8651#endif
8652 struct cfg80211_scan_request *request)
8653{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308654 hdd_adapter_t *pAdapter = NULL;
8655 hdd_context_t *pHddCtx = NULL;
8656 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308657 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 tCsrScanRequest scanRequest;
8659 tANI_U8 *channelList = NULL, i;
8660 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308661 int status;
8662 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008664
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8666 struct net_device *dev = NULL;
8667 if (NULL == request)
8668 {
8669 hddLog(VOS_TRACE_LEVEL_ERROR,
8670 "%s: scan req param null", __func__);
8671 return -EINVAL;
8672 }
8673 dev = request->wdev->netdev;
8674#endif
8675
8676 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8677 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8678 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 ENTER();
8681
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8683 __func__, hdd_device_modetoString(pAdapter->device_mode),
8684 pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308685 status = wlan_hdd_validate_context(pHddCtx);
8686
8687 if (0 != status)
8688 {
8689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8690 "%s: HDD context is not valid", __func__);
8691 return status;
8692 }
8693
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308694 if (NULL == pwextBuf)
8695 {
8696 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8697 __func__);
8698 return -EIO;
8699 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308700 cfg_param = pHddCtx->cfg_ini;
8701 pScanInfo = &pHddCtx->scan_info;
8702
Jeff Johnson295189b2012-06-20 16:38:30 -07008703#ifdef WLAN_BTAMP_FEATURE
8704 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008705 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008707 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 "%s: No scanning when AMP is on", __func__);
8709 return -EOPNOTSUPP;
8710 }
8711#endif
8712 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008713 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008715 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308716 "%s: Not scanning on device_mode = %s (%d)",
8717 __func__, hdd_device_modetoString(pAdapter->device_mode),
8718 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 return -EOPNOTSUPP;
8720 }
8721
8722 if (TRUE == pScanInfo->mScanPending)
8723 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308724 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8725 {
8726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8727 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008728 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 }
8730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308731 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008732 //Channel and action frame is pending
8733 //Otherwise Cancel Remain On Channel and allow Scan
8734 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008735 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008736 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008738 return -EBUSY;
8739 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008740#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008741 /* if tdls disagree scan right now, return immediately.
8742 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8743 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8744 */
8745 status = wlan_hdd_tdls_scan_callback (pAdapter,
8746 wiphy,
8747#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8748 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008749#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008750 request);
8751 if(status <= 0)
8752 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308753 if(!status)
8754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8755 "scan rejected %d", __func__, status);
8756 else
8757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8758 __func__, status);
8759
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008760 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008761 }
8762#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8765 {
8766 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008767 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308769 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008770 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8771 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308772 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 "%s: MAX TM Level Scan not allowed", __func__);
8774 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308775 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 }
8777 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8778
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008779 /* Check if scan is allowed at this point of time.
8780 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308781 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008782 {
8783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8784 return -EBUSY;
8785 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308786
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8788
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308789 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8790 (int)request->n_ssids);
8791
8792 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8793 * Becasue of this, driver is assuming that this is not wildcard scan and so
8794 * is not aging out the scan results.
8795 */
8796 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308798 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308800
8801 if ((request->ssids) && (0 < request->n_ssids))
8802 {
8803 tCsrSSIDInfo *SsidInfo;
8804 int j;
8805 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8806 /* Allocate num_ssid tCsrSSIDInfo structure */
8807 SsidInfo = scanRequest.SSIDs.SSIDList =
8808 ( tCsrSSIDInfo *)vos_mem_malloc(
8809 request->n_ssids*sizeof(tCsrSSIDInfo));
8810
8811 if(NULL == scanRequest.SSIDs.SSIDList)
8812 {
8813 hddLog(VOS_TRACE_LEVEL_ERROR,
8814 "%s: memory alloc failed SSIDInfo buffer", __func__);
8815 return -ENOMEM;
8816 }
8817
8818 /* copy all the ssid's and their length */
8819 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8820 {
8821 /* get the ssid length */
8822 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8823 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8824 SsidInfo->SSID.length);
8825 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8826 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8827 j, SsidInfo->SSID.ssId);
8828 }
8829 /* set the scan type to active */
8830 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8831 }
8832 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308834 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8835 TRACE_CODE_HDD_CFG80211_SCAN,
8836 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 /* set the scan type to active */
8838 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308840 else
8841 {
8842 /*Set the scan type to default type, in this case it is ACTIVE*/
8843 scanRequest.scanType = pScanInfo->scan_mode;
8844 }
8845 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8846 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008847
8848 /* set BSSType to default type */
8849 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8850
8851 /*TODO: scan the requested channels only*/
8852
8853 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308854 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308856 hddLog(VOS_TRACE_LEVEL_WARN,
8857 "No of Scan Channels exceeded limit: %d", request->n_channels);
8858 request->n_channels = MAX_CHANNEL;
8859 }
8860
8861 hddLog(VOS_TRACE_LEVEL_INFO,
8862 "No of Scan Channels: %d", request->n_channels);
8863
8864
8865 if( request->n_channels )
8866 {
8867 char chList [(request->n_channels*5)+1];
8868 int len;
8869 channelList = vos_mem_malloc( request->n_channels );
8870 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308871 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308872 hddLog(VOS_TRACE_LEVEL_ERROR,
8873 "%s: memory alloc failed channelList", __func__);
8874 status = -ENOMEM;
8875 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308876 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308877
8878 for( i = 0, len = 0; i < request->n_channels ; i++ )
8879 {
8880 channelList[i] = request->channels[i]->hw_value;
8881 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8882 }
8883
Nirav Shah20ac06f2013-12-12 18:14:06 +05308884 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308885 "Channel-List: %s ", chList);
8886 }
c_hpothu53512302014-04-15 18:49:53 +05308887
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308888 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8889 scanRequest.ChannelInfo.ChannelList = channelList;
8890
8891 /* set requestType to full scan */
8892 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8893
8894 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8895 * search (Flush on both full scan and social scan but not on single
8896 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8897 */
8898
8899 /* Supplicant does single channel scan after 8-way handshake
8900 * and in that case driver shoudnt flush scan results. If
8901 * driver flushes the scan results here and unfortunately if
8902 * the AP doesnt respond to our probe req then association
8903 * fails which is not desired
8904 */
8905
8906 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8907 {
8908 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8909 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8910 pAdapter->sessionId );
8911 }
8912
8913 if( request->ie_len )
8914 {
8915 /* save this for future association (join requires this) */
8916 /*TODO: Array needs to be converted to dynamic allocation,
8917 * as multiple ie.s can be sent in cfg80211_scan_request structure
8918 * CR 597966
8919 */
8920 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8921 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8922 pScanInfo->scanAddIE.length = request->ie_len;
8923
8924 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8925 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8926 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308928 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308930 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8931 memcpy( pwextBuf->roamProfile.addIEScan,
8932 request->ie, request->ie_len);
8933 }
8934 else
8935 {
8936 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8937 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 }
8939
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308940 }
8941 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8942 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8943
8944 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8945 request->ie_len);
8946 if (pP2pIe != NULL)
8947 {
8948#ifdef WLAN_FEATURE_P2P_DEBUG
8949 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8950 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8951 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308952 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308953 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8954 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8955 "Go nego completed to Connection is started");
8956 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8957 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308958 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308959 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8960 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308962 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8963 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8964 "Disconnected state to Connection is started");
8965 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8966 "for 4way Handshake");
8967 }
8968#endif
8969
8970 /* no_cck will be set during p2p find to disable 11b rates */
8971 if(TRUE == request->no_cck)
8972 {
8973 hddLog(VOS_TRACE_LEVEL_INFO,
8974 "%s: This is a P2P Search", __func__);
8975 scanRequest.p2pSearch = 1;
8976
8977 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05308978 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308979 /* set requestType to P2P Discovery */
8980 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
8981 }
8982
8983 /*
8984 Skip Dfs Channel in case of P2P Search
8985 if it is set in ini file
8986 */
8987 if(cfg_param->skipDfsChnlInP2pSearch)
8988 {
8989 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308990 }
8991 else
8992 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308993 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008995
Agarwal Ashish4f616132013-12-30 23:32:50 +05308996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 }
8998 }
8999
9000 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9001
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009002 /* acquire the wakelock to avoid the apps suspend during the scan. To
9003 * address the following issues.
9004 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9005 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9006 * for long time, this result in apps running at full power for long time.
9007 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9008 * be stuck in full power because of resume BMPS
9009 */
9010 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009011
Nirav Shah20ac06f2013-12-12 18:14:06 +05309012 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9013 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309014 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9015 scanRequest.requestType, scanRequest.scanType,
9016 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309017 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9018
Jeff Johnsone7245742012-09-05 17:12:55 -07009019 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 pAdapter->sessionId, &scanRequest, &scanId,
9021 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009022
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 if (eHAL_STATUS_SUCCESS != status)
9024 {
9025 hddLog(VOS_TRACE_LEVEL_ERROR,
9026 "%s: sme_ScanRequest returned error %d", __func__, status);
9027 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009028 if(eHAL_STATUS_RESOURCES == status)
9029 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9031 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009032 status = -EBUSY;
9033 } else {
9034 status = -EIO;
9035 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009036 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 goto free_mem;
9038 }
9039
9040 pScanInfo->mScanPending = TRUE;
9041 pAdapter->request = request;
9042 pScanInfo->scanId = scanId;
9043
9044 complete(&pScanInfo->scan_req_completion_event);
9045
9046free_mem:
9047 if( scanRequest.SSIDs.SSIDList )
9048 {
9049 vos_mem_free(scanRequest.SSIDs.SSIDList);
9050 }
9051
9052 if( channelList )
9053 vos_mem_free( channelList );
9054
9055 EXIT();
9056
9057 return status;
9058}
9059
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309060int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9061#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9062 struct net_device *dev,
9063#endif
9064 struct cfg80211_scan_request *request)
9065{
9066 int ret;
9067
9068 vos_ssr_protect(__func__);
9069 ret = __wlan_hdd_cfg80211_scan(wiphy,
9070#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9071 dev,
9072#endif
9073 request);
9074 vos_ssr_unprotect(__func__);
9075
9076 return ret;
9077}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009078
9079void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9080{
9081 v_U8_t iniDot11Mode =
9082 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9083 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9084
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309085 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9086 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009087 switch ( iniDot11Mode )
9088 {
9089 case eHDD_DOT11_MODE_AUTO:
9090 case eHDD_DOT11_MODE_11ac:
9091 case eHDD_DOT11_MODE_11ac_ONLY:
9092#ifdef WLAN_FEATURE_11AC
9093 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9094#else
9095 hddDot11Mode = eHDD_DOT11_MODE_11n;
9096#endif
9097 break;
9098 case eHDD_DOT11_MODE_11n:
9099 case eHDD_DOT11_MODE_11n_ONLY:
9100 hddDot11Mode = eHDD_DOT11_MODE_11n;
9101 break;
9102 default:
9103 hddDot11Mode = iniDot11Mode;
9104 break;
9105 }
9106 /* This call decides required channel bonding mode */
9107 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9108 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9109 operationChannel);
9110}
9111
Jeff Johnson295189b2012-06-20 16:38:30 -07009112/*
9113 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309114 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309116int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009117 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009118{
9119 int status = 0;
9120 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009121 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 v_U32_t roamId;
9123 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 eCsrAuthType RSNAuthType;
9125
9126 ENTER();
9127
9128 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009129 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9130
9131 status = wlan_hdd_validate_context(pHddCtx);
9132 if (status)
9133 {
9134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9135 "%s: HDD context is not valid!", __func__);
9136 return status;
9137 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309138
Jeff Johnson295189b2012-06-20 16:38:30 -07009139 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9140 {
9141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9142 return -EINVAL;
9143 }
9144
9145 pRoamProfile = &pWextState->roamProfile;
9146
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309147 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009149 hdd_station_ctx_t *pHddStaCtx;
9150 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009151
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309152 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9154 {
9155 /*QoS not enabled in cfg file*/
9156 pRoamProfile->uapsd_mask = 0;
9157 }
9158 else
9159 {
9160 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309161 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009162 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9163 }
9164
9165 pRoamProfile->SSIDs.numOfSSIDs = 1;
9166 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9167 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309168 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9170 ssid, ssid_len);
9171
9172 if (bssid)
9173 {
9174 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9175 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9176 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309177 /* Save BSSID in seperate variable as well, as RoamProfile
9178 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 case of join failure we should send valid BSSID to supplicant
9180 */
9181 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9182 WNI_CFG_BSSID_LEN);
9183 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009184 else
9185 {
9186 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9187 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009188
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309189 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9190 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009191 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9192 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309193 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 /*set gen ie*/
9195 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9196 /*set auth*/
9197 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9198 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009199#ifdef FEATURE_WLAN_WAPI
9200 if (pAdapter->wapi_info.nWapiMode)
9201 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009202 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 switch (pAdapter->wapi_info.wapiAuthMode)
9204 {
9205 case WAPI_AUTH_MODE_PSK:
9206 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009207 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 pAdapter->wapi_info.wapiAuthMode);
9209 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9210 break;
9211 }
9212 case WAPI_AUTH_MODE_CERT:
9213 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009214 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 pAdapter->wapi_info.wapiAuthMode);
9216 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9217 break;
9218 }
9219 } // End of switch
9220 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9221 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9222 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009223 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 pRoamProfile->AuthType.numEntries = 1;
9225 pRoamProfile->EncryptionType.numEntries = 1;
9226 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9227 pRoamProfile->mcEncryptionType.numEntries = 1;
9228 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9229 }
9230 }
9231#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309232#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309233 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309234 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9235 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9236 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309237 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9238 sizeof (tSirGtkOffloadParams));
9239 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309240 }
9241#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 pRoamProfile->csrPersona = pAdapter->device_mode;
9243
Jeff Johnson32d95a32012-09-10 13:15:23 -07009244 if( operatingChannel )
9245 {
9246 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9247 pRoamProfile->ChannelInfo.numOfChannels = 1;
9248 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009249 else
9250 {
9251 pRoamProfile->ChannelInfo.ChannelList = NULL;
9252 pRoamProfile->ChannelInfo.numOfChannels = 0;
9253 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009254 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9255 {
9256 hdd_select_cbmode(pAdapter,operatingChannel);
9257 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309258
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009259 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9260 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309261 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009262 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009263 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9264 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309265 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9266 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309267 {
9268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9269 "%s: Set HDD connState to eConnectionState_Connecting",
9270 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009271 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9272 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309273 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309274 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 pAdapter->sessionId, pRoamProfile, &roamId);
9276
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309277 if ((eHAL_STATUS_SUCCESS != status) &&
9278 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9279 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309280
9281 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9283 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9284 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309285 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009286 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309287 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009288
9289 pRoamProfile->ChannelInfo.ChannelList = NULL;
9290 pRoamProfile->ChannelInfo.numOfChannels = 0;
9291
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 }
9293 else
9294 {
9295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9296 return -EINVAL;
9297 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009298 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 return status;
9300}
9301
9302/*
9303 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9304 * This function is used to set the authentication type (OPEN/SHARED).
9305 *
9306 */
9307static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9308 enum nl80211_auth_type auth_type)
9309{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309310 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9312
9313 ENTER();
9314
9315 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309316 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309319 hddLog(VOS_TRACE_LEVEL_INFO,
9320 "%s: set authentication type to AUTOSWITCH", __func__);
9321 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9322 break;
9323
9324 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009325#ifdef WLAN_FEATURE_VOWIFI_11R
9326 case NL80211_AUTHTYPE_FT:
9327#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309328 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 "%s: set authentication type to OPEN", __func__);
9330 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9331 break;
9332
9333 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 "%s: set authentication type to SHARED", __func__);
9336 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9337 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009338#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309340 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 "%s: set authentication type to CCKM WPA", __func__);
9342 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9343 break;
9344#endif
9345
9346
9347 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309348 hddLog(VOS_TRACE_LEVEL_ERROR,
9349 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 auth_type);
9351 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9352 return -EINVAL;
9353 }
9354
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 pHddStaCtx->conn_info.authType;
9357 return 0;
9358}
9359
9360/*
9361 * FUNCTION: wlan_hdd_set_akm_suite
9362 * This function is used to set the key mgmt type(PSK/8021x).
9363 *
9364 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309365static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 u32 key_mgmt
9367 )
9368{
9369 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9370 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309371
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 /*set key mgmt type*/
9373 switch(key_mgmt)
9374 {
9375 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309376#ifdef WLAN_FEATURE_VOWIFI_11R
9377 case WLAN_AKM_SUITE_FT_PSK:
9378#endif
9379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 __func__);
9381 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9382 break;
9383
9384 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309385#ifdef WLAN_FEATURE_VOWIFI_11R
9386 case WLAN_AKM_SUITE_FT_8021X:
9387#endif
9388 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 __func__);
9390 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9391 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009392#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009393#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9394#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9395 case WLAN_AKM_SUITE_CCKM:
9396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9397 __func__);
9398 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9399 break;
9400#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009401#ifndef WLAN_AKM_SUITE_OSEN
9402#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9403 case WLAN_AKM_SUITE_OSEN:
9404 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9405 __func__);
9406 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9407 break;
9408#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009409
9410 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309411 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 __func__, key_mgmt);
9413 return -EINVAL;
9414
9415 }
9416 return 0;
9417}
9418
9419/*
9420 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309421 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 * (NONE/WEP40/WEP104/TKIP/CCMP).
9423 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309424static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9425 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 bool ucast
9427 )
9428{
9429 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309430 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9432
9433 ENTER();
9434
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309435 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 __func__, cipher);
9439 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9440 }
9441 else
9442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309443
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309445 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 {
9447 case IW_AUTH_CIPHER_NONE:
9448 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9449 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309452 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309456 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309458
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 case WLAN_CIPHER_SUITE_TKIP:
9460 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9461 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 case WLAN_CIPHER_SUITE_CCMP:
9464 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9465 break;
9466#ifdef FEATURE_WLAN_WAPI
9467 case WLAN_CIPHER_SUITE_SMS4:
9468 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9469 break;
9470#endif
9471
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009472#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 case WLAN_CIPHER_SUITE_KRK:
9474 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9475 break;
9476#endif
9477 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 __func__, cipher);
9480 return -EOPNOTSUPP;
9481 }
9482 }
9483
9484 if (ucast)
9485 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009487 __func__, encryptionType);
9488 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9489 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309490 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 encryptionType;
9492 }
9493 else
9494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309495 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 __func__, encryptionType);
9497 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9498 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9499 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9500 }
9501
9502 return 0;
9503}
9504
9505
9506/*
9507 * FUNCTION: wlan_hdd_cfg80211_set_ie
9508 * This function is used to parse WPA/RSN IE's.
9509 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309510int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9511 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 size_t ie_len
9513 )
9514{
9515 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9516 u8 *genie = ie;
9517 v_U16_t remLen = ie_len;
9518#ifdef FEATURE_WLAN_WAPI
9519 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9520 u16 *tmp;
9521 v_U16_t akmsuiteCount;
9522 int *akmlist;
9523#endif
9524 ENTER();
9525
9526 /* clear previous assocAddIE */
9527 pWextState->assocAddIE.length = 0;
9528 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009529 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009530
9531 while (remLen >= 2)
9532 {
9533 v_U16_t eLen = 0;
9534 v_U8_t elementId;
9535 elementId = *genie++;
9536 eLen = *genie++;
9537 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538
Arif Hussain6d2a3322013-11-17 19:50:10 -08009539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309541
9542 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009545 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 -07009546 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 "%s: Invalid WPA IE", __func__);
9549 return -EINVAL;
9550 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309551 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 {
9553 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309554 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9558 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009559 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9560 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 VOS_ASSERT(0);
9562 return -ENOMEM;
9563 }
9564 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9565 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9566 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309567
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9569 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9570 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9571 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9573 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9575 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9576 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9577 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9578 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9579 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309580 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309581 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 {
9583 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309586
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9588 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009589 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9590 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 VOS_ASSERT(0);
9592 return -ENOMEM;
9593 }
9594 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9595 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9596 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9599 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9600 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009601#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309602 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9603 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 /*Consider WFD IE, only for P2P Client */
9605 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9606 {
9607 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309610
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9612 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009613 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9614 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 VOS_ASSERT(0);
9616 return -ENOMEM;
9617 }
9618 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9619 // WPS IE + P2P IE + WFD IE
9620 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9621 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9624 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9625 }
9626#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009627 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309628 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009629 HS20_OUI_TYPE_SIZE)) )
9630 {
9631 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309632 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009633 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009634
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009635 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9636 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009637 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9638 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009639 VOS_ASSERT(0);
9640 return -ENOMEM;
9641 }
9642 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9643 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009644
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009645 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9646 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9647 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009648 /* Appending OSEN Information Element in Assiciation Request */
9649 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9650 OSEN_OUI_TYPE_SIZE)) )
9651 {
9652 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9653 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9654 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009655
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009656 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9657 {
9658 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9659 "Need bigger buffer space");
9660 VOS_ASSERT(0);
9661 return -ENOMEM;
9662 }
9663 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9664 pWextState->assocAddIE.length += eLen + 2;
9665
9666 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9667 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9668 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9669 }
9670
9671 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009672 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9673
9674 /* populating as ADDIE in beacon frames */
9675 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9676 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9677 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9678 {
9679 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9680 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9681 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9682 {
9683 hddLog(LOGE,
9684 "Coldn't pass "
9685 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9686 }
9687 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9688 else
9689 hddLog(LOGE,
9690 "Could not pass on "
9691 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9692
9693 /* IBSS mode doesn't contain params->proberesp_ies still
9694 beaconIE's need to be populated in probe response frames */
9695 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9696 {
9697 u16 rem_probe_resp_ie_len = eLen + 2;
9698 u8 probe_rsp_ie_len[3] = {0};
9699 u8 counter = 0;
9700
9701 /* Check Probe Resp Length if it is greater then 255 then
9702 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9703 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9704 not able Store More then 255 bytes into One Variable */
9705
9706 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9707 {
9708 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9709 {
9710 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9711 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9712 }
9713 else
9714 {
9715 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9716 rem_probe_resp_ie_len = 0;
9717 }
9718 }
9719
9720 rem_probe_resp_ie_len = 0;
9721
9722 if (probe_rsp_ie_len[0] > 0)
9723 {
9724 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9725 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9726 (tANI_U8*)(genie - 2),
9727 probe_rsp_ie_len[0], NULL,
9728 eANI_BOOLEAN_FALSE)
9729 == eHAL_STATUS_FAILURE)
9730 {
9731 hddLog(LOGE,
9732 "Could not pass"
9733 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9734 }
9735 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9736 }
9737
9738 if (probe_rsp_ie_len[1] > 0)
9739 {
9740 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9741 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9742 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9743 probe_rsp_ie_len[1], NULL,
9744 eANI_BOOLEAN_FALSE)
9745 == eHAL_STATUS_FAILURE)
9746 {
9747 hddLog(LOGE,
9748 "Could not pass"
9749 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9750 }
9751 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9752 }
9753
9754 if (probe_rsp_ie_len[2] > 0)
9755 {
9756 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9757 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9758 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9759 probe_rsp_ie_len[2], NULL,
9760 eANI_BOOLEAN_FALSE)
9761 == eHAL_STATUS_FAILURE)
9762 {
9763 hddLog(LOGE,
9764 "Could not pass"
9765 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9766 }
9767 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9768 }
9769
9770 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9771 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9772 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9773 {
9774 hddLog(LOGE,
9775 "Could not pass"
9776 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9777 }
9778 }
9779 else
9780 {
9781 // Reset WNI_CFG_PROBE_RSP Flags
9782 wlan_hdd_reset_prob_rspies(pAdapter);
9783
9784 hddLog(VOS_TRACE_LEVEL_INFO,
9785 "%s: No Probe Response IE received in set beacon",
9786 __func__);
9787 }
9788 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 break;
9790 case DOT11F_EID_RSN:
9791 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9792 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9793 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9794 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9795 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9796 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009797 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9798 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309799 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009800 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309801 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009802 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309803
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009804 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9805 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009806 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9807 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009808 VOS_ASSERT(0);
9809 return -ENOMEM;
9810 }
9811 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9812 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309813
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009814 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9815 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9816 break;
9817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009818#ifdef FEATURE_WLAN_WAPI
9819 case WLAN_EID_WAPI:
9820 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009821 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 pAdapter->wapi_info.nWapiMode);
9823 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309824 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 akmsuiteCount = WPA_GET_LE16(tmp);
9826 tmp = tmp + 1;
9827 akmlist = (int *)(tmp);
9828 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9829 {
9830 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9831 }
9832 else
9833 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009834 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 VOS_ASSERT(0);
9836 return -EINVAL;
9837 }
9838
9839 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9840 {
9841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009842 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309846 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009848 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9850 }
9851 break;
9852#endif
9853 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309854 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009856 /* when Unknown IE is received we should break and continue
9857 * to the next IE in the buffer instead we were returning
9858 * so changing this to break */
9859 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 }
9861 genie += eLen;
9862 remLen -= eLen;
9863 }
9864 EXIT();
9865 return 0;
9866}
9867
9868/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309869 * FUNCTION: hdd_isWPAIEPresent
9870 * Parse the received IE to find the WPA IE
9871 *
9872 */
9873static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9874{
9875 v_U8_t eLen = 0;
9876 v_U16_t remLen = ie_len;
9877 v_U8_t elementId = 0;
9878
9879 while (remLen >= 2)
9880 {
9881 elementId = *ie++;
9882 eLen = *ie++;
9883 remLen -= 2;
9884 if (eLen > remLen)
9885 {
9886 hddLog(VOS_TRACE_LEVEL_ERROR,
9887 "%s: IE length is wrong %d", __func__, eLen);
9888 return FALSE;
9889 }
9890 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9891 {
9892 /* OUI - 0x00 0X50 0XF2
9893 WPA Information Element - 0x01
9894 WPA version - 0x01*/
9895 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9896 return TRUE;
9897 }
9898 ie += eLen;
9899 remLen -= eLen;
9900 }
9901 return FALSE;
9902}
9903
9904/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309906 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 * parameters during connect operation.
9908 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309909int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 struct cfg80211_connect_params *req
9911 )
9912{
9913 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309914 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 ENTER();
9916
9917 /*set wpa version*/
9918 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9919
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309920 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309922 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 {
9924 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9925 }
9926 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9927 {
9928 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9929 }
9930 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931
9932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 pWextState->wpaVersion);
9934
9935 /*set authentication type*/
9936 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9937
9938 if (0 > status)
9939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309940 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 "%s: failed to set authentication type ", __func__);
9942 return status;
9943 }
9944
9945 /*set key mgmt type*/
9946 if (req->crypto.n_akm_suites)
9947 {
9948 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9949 if (0 > status)
9950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 __func__);
9953 return status;
9954 }
9955 }
9956
9957 /*set pairwise cipher type*/
9958 if (req->crypto.n_ciphers_pairwise)
9959 {
9960 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9961 req->crypto.ciphers_pairwise[0], true);
9962 if (0 > status)
9963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309964 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 "%s: failed to set unicast cipher type", __func__);
9966 return status;
9967 }
9968 }
9969 else
9970 {
9971 /*Reset previous cipher suite to none*/
9972 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
9973 if (0 > status)
9974 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309975 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 "%s: failed to set unicast cipher type", __func__);
9977 return status;
9978 }
9979 }
9980
9981 /*set group cipher type*/
9982 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
9983 false);
9984
9985 if (0 > status)
9986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 __func__);
9989 return status;
9990 }
9991
Chet Lanctot186b5732013-03-18 10:26:30 -07009992#ifdef WLAN_FEATURE_11W
9993 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
9994#endif
9995
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
9997 if (req->ie_len)
9998 {
9999 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10000 if ( 0 > status)
10001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 __func__);
10004 return status;
10005 }
10006 }
10007
10008 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010009 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 {
10011 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10012 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10013 )
10014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010015 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10017 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 __func__);
10020 return -EOPNOTSUPP;
10021 }
10022 else
10023 {
10024 u8 key_len = req->key_len;
10025 u8 key_idx = req->key_idx;
10026
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 && (CSR_MAX_NUM_KEY > key_idx)
10029 )
10030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010031 hddLog(VOS_TRACE_LEVEL_INFO,
10032 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 __func__, key_idx, key_len);
10034 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010035 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 (u8)key_len;
10039 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10040 }
10041 }
10042 }
10043 }
10044
10045 return status;
10046}
10047
10048/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010049 * FUNCTION: wlan_hdd_try_disconnect
10050 * This function is used to disconnect from previous
10051 * connection
10052 */
10053static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10054{
10055 long ret = 0;
10056 hdd_station_ctx_t *pHddStaCtx;
10057 eMib_dot11DesiredBssType connectedBssType;
10058
10059 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10060
10061 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10062
10063 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10064 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10065 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10066 {
10067 /* Issue disconnect to CSR */
10068 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10069 if( eHAL_STATUS_SUCCESS ==
10070 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10071 pAdapter->sessionId,
10072 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10073 {
10074 ret = wait_for_completion_interruptible_timeout(
10075 &pAdapter->disconnect_comp_var,
10076 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10077 if (0 >= ret)
10078 {
10079 hddLog(LOGE, FL("Failed to receive disconnect event"));
10080 return -EALREADY;
10081 }
10082 }
10083 }
10084 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10085 {
10086 ret = wait_for_completion_interruptible_timeout(
10087 &pAdapter->disconnect_comp_var,
10088 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10089 if (0 >= ret)
10090 {
10091 hddLog(LOGE, FL("Failed to receive disconnect event"));
10092 return -EALREADY;
10093 }
10094 }
10095
10096 return 0;
10097}
10098
10099/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010100 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010101 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 * parameters during connect operation.
10103 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010104static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 struct net_device *ndev,
10106 struct cfg80211_connect_params *req
10107 )
10108{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010109 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushik10728722014-05-14 16:20:25 +053010112 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010113
10114 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010115 if (NULL == pAdapter)
10116 {
10117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10118 "%s: HDD adapter context is Null", __func__);
10119 return -ENODEV;
10120 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10122 TRACE_CODE_HDD_CFG80211_CONNECT,
10123 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010124 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010125 "%s: device_mode = %s (%d)", __func__,
10126 hdd_device_modetoString(pAdapter->device_mode),
10127 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010128
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010129 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010130 if (!pHddCtx)
10131 {
10132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10133 "%s: HDD context is null", __func__);
10134 return VOS_STATUS_E_FAILURE;
10135 }
10136
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010137 status = wlan_hdd_validate_context(pHddCtx);
10138
10139 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10142 "%s: HDD context is not valid", __func__);
10143 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 }
10145
10146#ifdef WLAN_BTAMP_FEATURE
10147 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010148 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010150 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010152 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010153 }
10154#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010155
10156 //If Device Mode is Station Concurrent Sessions Exit BMps
10157 //P2P Mode will be taken care in Open/close adapter
10158 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
10159 (vos_concurrent_sessions_running()))
10160 {
10161 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10162 }
10163
10164 /*Try disconnecting if already in connected state*/
10165 status = wlan_hdd_try_disconnect(pAdapter);
10166 if ( 0 > status)
10167 {
10168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10169 " connection"));
10170 return -EALREADY;
10171 }
10172
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010174 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010175
10176 if ( 0 > status)
10177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 __func__);
10180 return status;
10181 }
10182
Mohit Khanna765234a2012-09-11 15:08:35 -070010183 if ( req->channel )
10184 {
10185 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10186 req->ssid_len, req->bssid,
10187 req->channel->hw_value);
10188 }
10189 else
10190 {
10191 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010192 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010193 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010194
10195 if (0 > status)
10196 {
10197 //ReEnable BMPS if disabled
10198 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10199 (NULL != pHddCtx))
10200 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010201 if (pHddCtx->hdd_wlan_suspended)
10202 {
10203 hdd_set_pwrparams(pHddCtx);
10204 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 //ReEnable Bmps and Imps back
10206 hdd_enable_bmps_imps(pHddCtx);
10207 }
10208
10209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10210 return status;
10211 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010212 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 EXIT();
10214 return status;
10215}
10216
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010217static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10218 struct net_device *ndev,
10219 struct cfg80211_connect_params *req)
10220{
10221 int ret;
10222 vos_ssr_protect(__func__);
10223 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10224 vos_ssr_unprotect(__func__);
10225
10226 return ret;
10227}
Jeff Johnson295189b2012-06-20 16:38:30 -070010228
10229/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010230 * FUNCTION: wlan_hdd_disconnect
10231 * This function is used to issue a disconnect request to SME
10232 */
10233int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10234{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010235 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010236 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010237 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010238 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010239
10240 status = wlan_hdd_validate_context(pHddCtx);
10241
10242 if (0 != status)
10243 {
10244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10245 "%s: HDD context is not valid", __func__);
10246 return status;
10247 }
10248
10249 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10251 "%s: Set HDD connState to eConnectionState_Disconnecting",
10252 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010253 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010254 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010255
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010256 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010257
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010258 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10259 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010260 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10261 {
10262 hddLog(VOS_TRACE_LEVEL_INFO,
10263 FL("status = %d, already disconnected"),
10264 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010265
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010266 }
10267 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010268 {
10269 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010270 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010271 __func__, (int)status );
10272 return -EINVAL;
10273 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010274 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010275 &pAdapter->disconnect_comp_var,
10276 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010277 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010278 {
10279 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010280 "%s: Failed to disconnect, timed out", __func__);
10281 return -ETIMEDOUT;
10282 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010283 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010284 {
10285 hddLog(VOS_TRACE_LEVEL_ERROR,
10286 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010287 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010288 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10290 FL("Set HDD connState to eConnectionState_NotConnected"));
10291 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10292
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010293 /*stop tx queues*/
10294 netif_tx_disable(pAdapter->dev);
10295 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010296 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010297}
10298
10299
10300/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010301 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 * This function is used to issue a disconnect request to SME
10303 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010304static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 struct net_device *dev,
10306 u16 reason
10307 )
10308{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Sushant Kaushik10728722014-05-14 16:20:25 +053010310 tCsrRoamProfile *pRoamProfile = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010311 int status;
Sushant Kaushik10728722014-05-14 16:20:25 +053010312 hdd_station_ctx_t *pHddStaCtx = NULL;
10313 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010314#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010315 tANI_U8 staIdx;
10316#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010317
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010319 if (NULL == pAdapter)
10320 {
10321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10322 "%s: HDD adapter context is Null", __func__);
10323 return -ENODEV;
10324 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10326 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10327 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010328 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10329 __func__, hdd_device_modetoString(pAdapter->device_mode),
10330 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010331
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10333 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010334
Sushant Kaushik10728722014-05-14 16:20:25 +053010335 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
10336 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010338 status = wlan_hdd_validate_context(pHddCtx);
10339
10340 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010341 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10343 "%s: HDD context is not valid", __func__);
10344 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010346
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 if (NULL != pRoamProfile)
10348 {
10349 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010350 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10351 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010353 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010355 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 switch(reason)
10357 {
10358 case WLAN_REASON_MIC_FAILURE:
10359 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10360 break;
10361
10362 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10363 case WLAN_REASON_DISASSOC_AP_BUSY:
10364 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10365 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10366 break;
10367
10368 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10369 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010370 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10372 break;
10373
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 default:
10375 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10376 break;
10377 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010378 pScanInfo = &pHddCtx->scan_info;
10379 if (pScanInfo->mScanPending)
10380 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010381 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010382 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010383 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10384 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010386
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010387#ifdef FEATURE_WLAN_TDLS
10388 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010389 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010390 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010391 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10392 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010393 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010394 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010395 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010396 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010397 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010398 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010399 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010400 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010401 pAdapter->sessionId,
10402 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010403 }
10404 }
10405#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010406 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010407 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10408 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 {
10410 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010411 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 __func__, (int)status );
10413 return -EINVAL;
10414 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010416 else
10417 {
10418 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10419 "called while in %d state", __func__,
10420 pHddStaCtx->conn_info.connState);
10421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 }
10423 else
10424 {
10425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10426 }
10427
10428 return status;
10429}
10430
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010431static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10432 struct net_device *dev,
10433 u16 reason
10434 )
10435{
10436 int ret;
10437 vos_ssr_protect(__func__);
10438 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10439 vos_ssr_unprotect(__func__);
10440
10441 return ret;
10442}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010443
Jeff Johnson295189b2012-06-20 16:38:30 -070010444/*
10445 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 * settings in IBSS mode.
10448 */
10449static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010450 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 struct cfg80211_ibss_params *params
10452 )
10453{
10454 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10457 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 ENTER();
10460
10461 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010462 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010463
10464 if (params->ie_len && ( NULL != params->ie) )
10465 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010466 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10467 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 {
10469 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10470 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10471 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010472 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010474 tDot11fIEWPA dot11WPAIE;
10475 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010476 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010477
Wilson Yang00256342013-10-10 23:13:38 -070010478 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010479 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10480 params->ie_len, DOT11F_EID_WPA);
10481 if ( NULL != ie )
10482 {
10483 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10484 // Unpack the WPA IE
10485 //Skip past the EID byte and length byte - and four byte WiFi OUI
10486 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10487 &ie[2+4],
10488 ie[1] - 4,
10489 &dot11WPAIE);
10490 /*Extract the multicast cipher, the encType for unicast
10491 cipher for wpa-none is none*/
10492 encryptionType =
10493 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010495 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010496
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10498
10499 if (0 > status)
10500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 __func__);
10503 return status;
10504 }
10505 }
10506
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010507 pWextState->roamProfile.AuthType.authType[0] =
10508 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10510
10511 if (params->privacy)
10512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010513 /* Security enabled IBSS, At this time there is no information available
10514 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010516 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010518 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 *enable privacy bit in beacons */
10520
10521 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10522 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010523 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10524 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10526 pWextState->roamProfile.EncryptionType.numEntries = 1;
10527 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 return status;
10529}
10530
10531/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010532 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010535static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 struct net_device *dev,
10537 struct cfg80211_ibss_params *params
10538 )
10539{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010540 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10542 tCsrRoamProfile *pRoamProfile;
10543 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010544 bool alloc_bssid = VOS_FALSE;
Sushant Kaushik10728722014-05-14 16:20:25 +053010545 hdd_station_ctx_t *pHddStaCtx = NULL;
10546 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010547
10548 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010549 if (NULL == pAdapter)
10550 {
10551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10552 "%s: HDD adapter context is Null", __func__);
10553 return -ENODEV;
10554 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010555 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10556 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10557 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010558 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010559 "%s: device_mode = %s (%d)", __func__,
10560 hdd_device_modetoString(pAdapter->device_mode),
10561 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010562
Sushant Kaushik10728722014-05-14 16:20:25 +053010563 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10564 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010565 status = wlan_hdd_validate_context(pHddCtx);
10566
10567 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10570 "%s: HDD context is not valid", __func__);
10571 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 }
10573
10574 if (NULL == pWextState)
10575 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010576 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 __func__);
10578 return -EIO;
10579 }
10580
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010581 /*Try disconnecting if already in connected state*/
10582 status = wlan_hdd_try_disconnect(pAdapter);
10583 if ( 0 > status)
10584 {
10585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10586 " IBSS connection"));
10587 return -EALREADY;
10588 }
10589
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 pRoamProfile = &pWextState->roamProfile;
10591
10592 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010594 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010595 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010596 return -EINVAL;
10597 }
10598
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010599 /* BSSID is provided by upper layers hence no need to AUTO generate */
10600 if (NULL != params->bssid) {
10601 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10602 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10603 hddLog (VOS_TRACE_LEVEL_ERROR,
10604 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10605 return -EIO;
10606 }
10607 }
krunal sonie9002db2013-11-25 14:24:17 -080010608 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10609 {
10610 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10611 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10612 {
10613 hddLog (VOS_TRACE_LEVEL_ERROR,
10614 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10615 return -EIO;
10616 }
10617 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10618 if (!params->bssid)
10619 {
10620 hddLog (VOS_TRACE_LEVEL_ERROR,
10621 "%s:Failed memory allocation", __func__);
10622 return -EIO;
10623 }
10624 vos_mem_copy((v_U8_t *)params->bssid,
10625 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10626 VOS_MAC_ADDR_SIZE);
10627 alloc_bssid = VOS_TRUE;
10628 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010629
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010631 if (NULL !=
10632#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10633 params->chandef.chan)
10634#else
10635 params->channel)
10636#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010637 {
10638 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010639 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10640 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10641 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10642 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010643
10644 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010645 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010646 ieee80211_frequency_to_channel(
10647#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10648 params->chandef.chan->center_freq);
10649#else
10650 params->channel->center_freq);
10651#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010652
10653 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10654 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10657 __func__);
10658 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010660
10661 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010662 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010663 if (channelNum == validChan[indx])
10664 {
10665 break;
10666 }
10667 }
10668 if (indx >= numChans)
10669 {
10670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 __func__, channelNum);
10672 return -EINVAL;
10673 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010674 /* Set the Operational Channel */
10675 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10676 channelNum);
10677 pRoamProfile->ChannelInfo.numOfChannels = 1;
10678 pHddStaCtx->conn_info.operationChannel = channelNum;
10679 pRoamProfile->ChannelInfo.ChannelList =
10680 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 }
10682
10683 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010684 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 if (status < 0)
10686 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 __func__);
10689 return status;
10690 }
10691
10692 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010693 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010694 params->ssid_len, params->bssid,
10695 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010696
10697 if (0 > status)
10698 {
10699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10700 return status;
10701 }
10702
krunal sonie9002db2013-11-25 14:24:17 -080010703 if (NULL != params->bssid &&
10704 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10705 alloc_bssid == VOS_TRUE)
10706 {
10707 vos_mem_free(params->bssid);
10708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 return 0;
10710}
10711
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010712static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10713 struct net_device *dev,
10714 struct cfg80211_ibss_params *params
10715 )
10716{
10717 int ret = 0;
10718
10719 vos_ssr_protect(__func__);
10720 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10721 vos_ssr_unprotect(__func__);
10722
10723 return ret;
10724}
10725
Jeff Johnson295189b2012-06-20 16:38:30 -070010726/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010727 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010728 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010730static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 struct net_device *dev
10732 )
10733{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Sushant Kaushik10728722014-05-14 16:20:25 +053010735 hdd_wext_state_t *pWextState = NULL;
10736 tCsrRoamProfile *pRoamProfile = NULL;
10737 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010738 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010739
10740 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010741 if (NULL == pAdapter)
10742 {
10743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10744 "%s: HDD adapter context is Null", __func__);
10745 return -ENODEV;
10746 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10748 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10749 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Sushant Kaushik10728722014-05-14 16:20:25 +053010750 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10751 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010752 status = wlan_hdd_validate_context(pHddCtx);
10753
10754 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010755 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10757 "%s: HDD context is not valid", __func__);
10758 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010759 }
10760
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010761 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10762 hdd_device_modetoString(pAdapter->device_mode),
10763 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 if (NULL == pWextState)
10765 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010766 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 __func__);
10768 return -EIO;
10769 }
10770
10771 pRoamProfile = &pWextState->roamProfile;
10772
10773 /* Issue disconnect only if interface type is set to IBSS */
10774 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010776 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 __func__);
10778 return -EINVAL;
10779 }
10780
10781 /* Issue Disconnect request */
10782 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10783 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10784 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10785
10786 return 0;
10787}
10788
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010789static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10790 struct net_device *dev
10791 )
10792{
10793 int ret = 0;
10794
10795 vos_ssr_protect(__func__);
10796 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10797 vos_ssr_unprotect(__func__);
10798
10799 return ret;
10800}
10801
Jeff Johnson295189b2012-06-20 16:38:30 -070010802/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010803 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 * This function is used to set the phy parameters
10805 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10806 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010807static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 u32 changed)
10809{
10810 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10811 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010812 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010813
10814 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10816 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10817 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010818 status = wlan_hdd_validate_context(pHddCtx);
10819
10820 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010821 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10823 "%s: HDD context is not valid", __func__);
10824 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010825 }
10826
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10828 {
10829 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10830 WNI_CFG_RTS_THRESHOLD_STAMAX :
10831 wiphy->rts_threshold;
10832
10833 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010834 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010836 hddLog(VOS_TRACE_LEVEL_ERROR,
10837 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010838 __func__, rts_threshold);
10839 return -EINVAL;
10840 }
10841
10842 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10843 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010844 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010846 hddLog(VOS_TRACE_LEVEL_ERROR,
10847 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 __func__, rts_threshold);
10849 return -EIO;
10850 }
10851
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010852 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 rts_threshold);
10854 }
10855
10856 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10857 {
10858 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10859 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10860 wiphy->frag_threshold;
10861
10862 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010865 hddLog(VOS_TRACE_LEVEL_ERROR,
10866 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 frag_threshold);
10868 return -EINVAL;
10869 }
10870
10871 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10872 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010873 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010875 hddLog(VOS_TRACE_LEVEL_ERROR,
10876 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 __func__, frag_threshold);
10878 return -EIO;
10879 }
10880
10881 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10882 frag_threshold);
10883 }
10884
10885 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10886 || (changed & WIPHY_PARAM_RETRY_LONG))
10887 {
10888 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10889 wiphy->retry_short :
10890 wiphy->retry_long;
10891
10892 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10893 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 __func__, retry_value);
10897 return -EINVAL;
10898 }
10899
10900 if (changed & WIPHY_PARAM_RETRY_SHORT)
10901 {
10902 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10903 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010904 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010906 hddLog(VOS_TRACE_LEVEL_ERROR,
10907 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 __func__, retry_value);
10909 return -EIO;
10910 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010911 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010912 __func__, retry_value);
10913 }
10914 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10915 {
10916 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10917 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010918 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010920 hddLog(VOS_TRACE_LEVEL_ERROR,
10921 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 __func__, retry_value);
10923 return -EIO;
10924 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010925 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 __func__, retry_value);
10927 }
10928 }
10929
10930 return 0;
10931}
10932
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010933static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10934 u32 changed)
10935{
10936 int ret;
10937
10938 vos_ssr_protect(__func__);
10939 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10940 vos_ssr_unprotect(__func__);
10941
10942 return ret;
10943}
10944
Jeff Johnson295189b2012-06-20 16:38:30 -070010945/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010946 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 * This function is used to set the txpower
10948 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010949static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010950#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10951 struct wireless_dev *wdev,
10952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010953#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010955#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010956 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010957#endif
10958 int dbm)
10959{
10960 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010961 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010962 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10963 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010964 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010965
10966 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010967 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10968 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10969 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010970 status = wlan_hdd_validate_context(pHddCtx);
10971
10972 if (0 != status)
10973 {
10974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10975 "%s: HDD context is not valid", __func__);
10976 return status;
10977 }
10978
10979 hHal = pHddCtx->hHal;
10980
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010981 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10982 dbm, ccmCfgSetCallback,
10983 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010985 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10987 return -EIO;
10988 }
10989
10990 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
10991 dbm);
10992
10993 switch(type)
10994 {
10995 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
10996 /* Fall through */
10997 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
10998 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
10999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11001 __func__);
11002 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 }
11004 break;
11005 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 __func__);
11008 return -EOPNOTSUPP;
11009 break;
11010 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11012 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 return -EIO;
11014 }
11015
11016 return 0;
11017}
11018
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011019static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11020#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11021 struct wireless_dev *wdev,
11022#endif
11023#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11024 enum tx_power_setting type,
11025#else
11026 enum nl80211_tx_power_setting type,
11027#endif
11028 int dbm)
11029{
11030 int ret;
11031 vos_ssr_protect(__func__);
11032 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11033#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11034 wdev,
11035#endif
11036#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11037 type,
11038#else
11039 type,
11040#endif
11041 dbm);
11042 vos_ssr_unprotect(__func__);
11043
11044 return ret;
11045}
11046
Jeff Johnson295189b2012-06-20 16:38:30 -070011047/*
11048 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11049 * This function is used to read the txpower
11050 */
Yue Maf49ba872013-08-19 12:04:25 -070011051static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11052#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11053 struct wireless_dev *wdev,
11054#endif
11055 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011056{
11057
11058 hdd_adapter_t *pAdapter;
11059 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011060 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011061
Jeff Johnsone7245742012-09-05 17:12:55 -070011062 ENTER();
11063
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011064 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011065
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011066 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011067 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11069 "%s: HDD context is not valid", __func__);
11070 *dbm = 0;
11071 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011072 }
11073
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11075 if (NULL == pAdapter)
11076 {
11077 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11078 return -ENOENT;
11079 }
11080
11081 wlan_hdd_get_classAstats(pAdapter);
11082 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11083
Jeff Johnsone7245742012-09-05 17:12:55 -070011084 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 return 0;
11086}
11087
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011088static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 u8* mac, struct station_info *sinfo)
11090{
11091 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11092 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11093 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011094 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011095
11096 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11097 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011098
11099 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11100 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11101 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11102 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11103 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11104 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11105 tANI_U16 maxRate = 0;
11106 tANI_U16 myRate;
11107 tANI_U16 currentRate = 0;
11108 tANI_U8 maxSpeedMCS = 0;
11109 tANI_U8 maxMCSIdx = 0;
11110 tANI_U8 rateFlag = 1;
11111 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011112 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011113 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011114
Leo Chang6f8870f2013-03-26 18:11:36 -070011115#ifdef WLAN_FEATURE_11AC
11116 tANI_U32 vht_mcs_map;
11117 eDataRate11ACMaxMcs vhtMaxMcs;
11118#endif /* WLAN_FEATURE_11AC */
11119
Jeff Johnsone7245742012-09-05 17:12:55 -070011120 ENTER();
11121
Jeff Johnson295189b2012-06-20 16:38:30 -070011122 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11123 (0 == ssidlen))
11124 {
11125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11126 " Invalid ssidlen, %d", __func__, ssidlen);
11127 /*To keep GUI happy*/
11128 return 0;
11129 }
11130
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011131 status = wlan_hdd_validate_context(pHddCtx);
11132
11133 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011134 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11136 "%s: HDD context is not valid", __func__);
11137 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011138 }
11139
Jeff Johnson295189b2012-06-20 16:38:30 -070011140
Kiet Lam3b17fc82013-09-27 05:24:08 +053011141 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11142 sinfo->filled |= STATION_INFO_SIGNAL;
11143
c_hpothu09f19542014-05-30 21:53:31 +053011144 wlan_hdd_get_station_stats(pAdapter);
11145 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11146
11147 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011148 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11149 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11150 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11151 {
11152 rate_flags = pAdapter->maxRateFlags;
11153 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011154
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 //convert to the UI units of 100kbps
11156 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11157
11158#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011159 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 -070011160 sinfo->signal,
11161 pCfg->reportMaxLinkSpeed,
11162 myRate,
11163 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011164 (int) pCfg->linkSpeedRssiMid,
11165 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011166 (int) rate_flags,
11167 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011168#endif //LINKSPEED_DEBUG_ENABLED
11169
11170 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11171 {
11172 // we do not want to necessarily report the current speed
11173 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11174 {
11175 // report the max possible speed
11176 rssidx = 0;
11177 }
11178 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11179 {
11180 // report the max possible speed with RSSI scaling
11181 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11182 {
11183 // report the max possible speed
11184 rssidx = 0;
11185 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011186 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011187 {
11188 // report middle speed
11189 rssidx = 1;
11190 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011191 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11192 {
11193 // report middle speed
11194 rssidx = 2;
11195 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 else
11197 {
11198 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011199 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 }
11201 }
11202 else
11203 {
11204 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11205 hddLog(VOS_TRACE_LEVEL_ERROR,
11206 "%s: Invalid value for reportMaxLinkSpeed: %u",
11207 __func__, pCfg->reportMaxLinkSpeed);
11208 rssidx = 0;
11209 }
11210
11211 maxRate = 0;
11212
11213 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011214 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11215 OperationalRates, &ORLeng))
11216 {
11217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11218 /*To keep GUI happy*/
11219 return 0;
11220 }
11221
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 for (i = 0; i < ORLeng; i++)
11223 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011224 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 {
11226 /* Validate Rate Set */
11227 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11228 {
11229 currentRate = supported_data_rate[j].supported_rate[rssidx];
11230 break;
11231 }
11232 }
11233 /* Update MAX rate */
11234 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11235 }
11236
11237 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011238 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11239 ExtendedRates, &ERLeng))
11240 {
11241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11242 /*To keep GUI happy*/
11243 return 0;
11244 }
11245
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 for (i = 0; i < ERLeng; i++)
11247 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011248 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 {
11250 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11251 {
11252 currentRate = supported_data_rate[j].supported_rate[rssidx];
11253 break;
11254 }
11255 }
11256 /* Update MAX rate */
11257 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11258 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011259 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011260 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011261 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011262 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011263 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011265 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11266 MCSRates, &MCSLeng))
11267 {
11268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11269 /*To keep GUI happy*/
11270 return 0;
11271 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011273#ifdef WLAN_FEATURE_11AC
11274 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011275 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011277 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011278 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011279 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011281 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011283 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011285 maxMCSIdx = 7;
11286 }
11287 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11288 {
11289 maxMCSIdx = 8;
11290 }
11291 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11292 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011293 //VHT20 is supporting 0~8
11294 if (rate_flags & eHAL_TX_RATE_VHT20)
11295 maxMCSIdx = 8;
11296 else
11297 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011298 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011299
11300 if (rate_flags & eHAL_TX_RATE_VHT80)
11301 {
11302 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11303 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11304 }
11305 else if (rate_flags & eHAL_TX_RATE_VHT40)
11306 {
11307 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11308 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11309 }
11310 else if (rate_flags & eHAL_TX_RATE_VHT20)
11311 {
11312 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11313 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11314 }
11315
Leo Chang6f8870f2013-03-26 18:11:36 -070011316 maxSpeedMCS = 1;
11317 if (currentRate > maxRate)
11318 {
11319 maxRate = currentRate;
11320 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011321
Leo Chang6f8870f2013-03-26 18:11:36 -070011322 }
11323 else
11324#endif /* WLAN_FEATURE_11AC */
11325 {
11326 if (rate_flags & eHAL_TX_RATE_HT40)
11327 {
11328 rateFlag |= 1;
11329 }
11330 if (rate_flags & eHAL_TX_RATE_SGI)
11331 {
11332 rateFlag |= 2;
11333 }
11334
11335 for (i = 0; i < MCSLeng; i++)
11336 {
11337 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11338 for (j = 0; j < temp; j++)
11339 {
11340 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11341 {
11342 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11343 break;
11344 }
11345 }
11346 if ((j < temp) && (currentRate > maxRate))
11347 {
11348 maxRate = currentRate;
11349 maxSpeedMCS = 1;
11350 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 }
11353 }
11354 }
11355
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011356 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11357 {
11358 maxRate = myRate;
11359 maxSpeedMCS = 1;
11360 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11361 }
11362
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011364 if (((maxRate < myRate) && (0 == rssidx)) ||
11365 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 {
11367 maxRate = myRate;
11368 if (rate_flags & eHAL_TX_RATE_LEGACY)
11369 {
11370 maxSpeedMCS = 0;
11371 }
11372 else
11373 {
11374 maxSpeedMCS = 1;
11375 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11376 }
11377 }
11378
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011379 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 {
11381 sinfo->txrate.legacy = maxRate;
11382#ifdef LINKSPEED_DEBUG_ENABLED
11383 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11384#endif //LINKSPEED_DEBUG_ENABLED
11385 }
11386 else
11387 {
11388 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011389#ifdef WLAN_FEATURE_11AC
11390 sinfo->txrate.nss = 1;
11391 if (rate_flags & eHAL_TX_RATE_VHT80)
11392 {
11393 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011394 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011395 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011396 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011397 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011398 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11399 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11400 }
11401 else if (rate_flags & eHAL_TX_RATE_VHT20)
11402 {
11403 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11404 }
11405#endif /* WLAN_FEATURE_11AC */
11406 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11407 {
11408 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11409 if (rate_flags & eHAL_TX_RATE_HT40)
11410 {
11411 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11412 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011413 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 if (rate_flags & eHAL_TX_RATE_SGI)
11415 {
11416 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11417 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011418
Jeff Johnson295189b2012-06-20 16:38:30 -070011419#ifdef LINKSPEED_DEBUG_ENABLED
11420 pr_info("Reporting MCS rate %d flags %x\n",
11421 sinfo->txrate.mcs,
11422 sinfo->txrate.flags );
11423#endif //LINKSPEED_DEBUG_ENABLED
11424 }
11425 }
11426 else
11427 {
11428 // report current rate instead of max rate
11429
11430 if (rate_flags & eHAL_TX_RATE_LEGACY)
11431 {
11432 //provide to the UI in units of 100kbps
11433 sinfo->txrate.legacy = myRate;
11434#ifdef LINKSPEED_DEBUG_ENABLED
11435 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11436#endif //LINKSPEED_DEBUG_ENABLED
11437 }
11438 else
11439 {
11440 //must be MCS
11441 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011442#ifdef WLAN_FEATURE_11AC
11443 sinfo->txrate.nss = 1;
11444 if (rate_flags & eHAL_TX_RATE_VHT80)
11445 {
11446 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11447 }
11448 else
11449#endif /* WLAN_FEATURE_11AC */
11450 {
11451 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11452 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011453 if (rate_flags & eHAL_TX_RATE_SGI)
11454 {
11455 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11456 }
11457 if (rate_flags & eHAL_TX_RATE_HT40)
11458 {
11459 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11460 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011461#ifdef WLAN_FEATURE_11AC
11462 else if (rate_flags & eHAL_TX_RATE_VHT80)
11463 {
11464 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11465 }
11466#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011467#ifdef LINKSPEED_DEBUG_ENABLED
11468 pr_info("Reporting actual MCS rate %d flags %x\n",
11469 sinfo->txrate.mcs,
11470 sinfo->txrate.flags );
11471#endif //LINKSPEED_DEBUG_ENABLED
11472 }
11473 }
11474 sinfo->filled |= STATION_INFO_TX_BITRATE;
11475
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011476 sinfo->tx_packets =
11477 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11478 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11479 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11480 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11481
11482 sinfo->tx_retries =
11483 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11484 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11485 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11486 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11487
11488 sinfo->tx_failed =
11489 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11490 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11491 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11492 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11493
11494 sinfo->filled |=
11495 STATION_INFO_TX_PACKETS |
11496 STATION_INFO_TX_RETRIES |
11497 STATION_INFO_TX_FAILED;
11498
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011499 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11500 TRACE_CODE_HDD_CFG80211_GET_STA,
11501 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011502 EXIT();
11503 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011504}
11505
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011506static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11507 u8* mac, struct station_info *sinfo)
11508{
11509 int ret;
11510
11511 vos_ssr_protect(__func__);
11512 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11513 vos_ssr_unprotect(__func__);
11514
11515 return ret;
11516}
11517
11518static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011519 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011520{
11521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011522 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011524 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011525
Jeff Johnsone7245742012-09-05 17:12:55 -070011526 ENTER();
11527
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 if (NULL == pAdapter)
11529 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 return -ENODEV;
11532 }
11533
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011534 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11535 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11536 pAdapter->sessionId, timeout));
11537
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011538 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011539 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011540
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011541 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11544 "%s: HDD context is not valid", __func__);
11545 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011546 }
11547
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011548 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11549 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11550 (pHddCtx->cfg_ini->fhostArpOffload) &&
11551 (eConnectionState_Associated ==
11552 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11553 {
Amar Singhald53568e2013-09-26 11:03:45 -070011554
11555 hddLog(VOS_TRACE_LEVEL_INFO,
11556 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011557 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011558 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11559 {
11560 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011561 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011562 __func__, vos_status);
11563 }
11564 }
11565
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 /**The get power cmd from the supplicant gets updated by the nl only
11567 *on successful execution of the function call
11568 *we are oppositely mapped w.r.t mode in the driver
11569 **/
11570 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11571
Kiet Lam94fd2922014-06-18 19:12:43 -070011572 if (!mode)
11573 {
11574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11575 "%s: DHCP start indicated through power save", __func__);
11576
11577 pHddCtx->btCoexModeSet = TRUE;
11578 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11579 pAdapter->sessionId);
11580 }
11581 else
11582 {
11583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11584 "%s: DHCP stop indicated through power save", __func__);
11585
11586 pHddCtx->btCoexModeSet = FALSE;
11587 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11588 pAdapter->sessionId);
11589 }
11590
Jeff Johnsone7245742012-09-05 17:12:55 -070011591 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 if (VOS_STATUS_E_FAILURE == vos_status)
11593 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11595 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 return -EINVAL;
11597 }
11598 return 0;
11599}
11600
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011601static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11602 struct net_device *dev, bool mode, int timeout)
11603{
11604 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011605
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011606 vos_ssr_protect(__func__);
11607 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11608 vos_ssr_unprotect(__func__);
11609
11610 return ret;
11611}
Jeff Johnson295189b2012-06-20 16:38:30 -070011612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11613static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11614 struct net_device *netdev,
11615 u8 key_index)
11616{
Jeff Johnsone7245742012-09-05 17:12:55 -070011617 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 return 0;
11619}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011620#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011621
11622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11623static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11624 struct net_device *dev,
11625 struct ieee80211_txq_params *params)
11626{
Jeff Johnsone7245742012-09-05 17:12:55 -070011627 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 return 0;
11629}
11630#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11631static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11632 struct ieee80211_txq_params *params)
11633{
Jeff Johnsone7245742012-09-05 17:12:55 -070011634 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 return 0;
11636}
11637#endif //LINUX_VERSION_CODE
11638
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011639static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011640 struct net_device *dev, u8 *mac)
11641{
11642 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011643 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011644 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011645 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011646 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011647
Jeff Johnsone7245742012-09-05 17:12:55 -070011648 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011649
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011650 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 return -EINVAL;
11654 }
11655
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011656 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11657 TRACE_CODE_HDD_CFG80211_DEL_STA,
11658 pAdapter->sessionId, pAdapter->device_mode));
11659
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11661 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011662
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011663 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011664 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11666 "%s: HDD context is not valid", __func__);
11667 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011668 }
11669
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011671 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 )
11673 {
11674 if( NULL == mac )
11675 {
11676 v_U16_t i;
11677 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11678 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011679 if ((pAdapter->aStaInfo[i].isUsed) &&
11680 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 {
11682 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11683 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011684 "%s: Delete STA with MAC::"
11685 MAC_ADDRESS_STR,
11686 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011687 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11688 if (VOS_IS_STATUS_SUCCESS(vos_status))
11689 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 }
11691 }
11692 }
11693 else
11694 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011695
11696 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11697 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11698 {
11699 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011700 "%s: Skip this DEL STA as this is not used::"
11701 MAC_ADDRESS_STR,
11702 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011703 return -ENOENT;
11704 }
11705
11706 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11707 {
11708 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011709 "%s: Skip this DEL STA as deauth is in progress::"
11710 MAC_ADDRESS_STR,
11711 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011712 return -ENOENT;
11713 }
11714
11715 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11716
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 hddLog(VOS_TRACE_LEVEL_INFO,
11718 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011719 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011720 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011721 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011722
11723 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11724 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11725 {
11726 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11727 hddLog(VOS_TRACE_LEVEL_INFO,
11728 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011729 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011730 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011731 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011732 return -ENOENT;
11733 }
11734
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 }
11736 }
11737
11738 EXIT();
11739
11740 return 0;
11741}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011742static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11743 struct net_device *dev, u8 *mac)
11744{
11745 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011746
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011747 vos_ssr_protect(__func__);
11748 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11749 vos_ssr_unprotect(__func__);
11750
11751 return ret;
11752}
11753
11754static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011755 struct net_device *dev, u8 *mac, struct station_parameters *params)
11756{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011757 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011758 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011759#ifdef FEATURE_WLAN_TDLS
11760 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011761 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053011762 if (NULL == pAdapter)
11763 {
11764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11765 "%s: HDD adapter context is Null", __func__);
11766 return -ENODEV;
11767 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011768 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11769 TRACE_CODE_HDD_CFG80211_ADD_STA,
11770 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011771 mask = params->sta_flags_mask;
11772
11773 set = params->sta_flags_set;
11774
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011775#ifdef WLAN_FEATURE_TDLS_DEBUG
11776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11777 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11778 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11779#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011780
11781 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11782 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011783 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011784 }
11785 }
11786#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011787 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011788}
11789
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011790static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11791 struct net_device *dev, u8 *mac, struct station_parameters *params)
11792{
11793 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011794
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011795 vos_ssr_protect(__func__);
11796 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11797 vos_ssr_unprotect(__func__);
11798
11799 return ret;
11800}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011801#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011802
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011803static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011804 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011805{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011808 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011809 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011810 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011812 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011814 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11815 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011816
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011818 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011819 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011821 return -EINVAL;
11822 }
11823
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011824 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11825 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011826
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011827 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11830 "%s: HDD context is not valid", __func__);
11831 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011832 }
11833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011834 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011835 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011836 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011837
Agarwal Ashish3da95242014-05-21 14:57:17 +053011838 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011839 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011840 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011841 pmksa->bssid, WNI_CFG_BSSID_LEN))
11842 {
11843 /* BSSID matched previous entry. Overwrite it. */
11844 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011845 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011846 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011847 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011848 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011850 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011851 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011852 dump_bssid(pmksa->bssid);
11853 dump_pmkid(halHandle, pmksa->pmkid);
11854 break;
11855 }
11856 }
11857
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011858 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011859 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011860
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011861 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011862 {
11863 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011864 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011865 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011866 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011867 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011868 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011869 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11870 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011871 dump_bssid(pmksa->bssid);
11872 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011874 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011875 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11876 pHddStaCtx->PMKIDCacheIndex++;
11877 else
11878 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011879 }
11880
11881
11882 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011883 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11884 __func__, pHddStaCtx->PMKIDCacheIndex );
11885
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011886 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011887 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011888 pHddStaCtx->PMKIDCache,
11889 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011890 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11891 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11892 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011893 return 0;
11894}
11895
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011896static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11897 struct cfg80211_pmksa *pmksa)
11898{
11899 int ret;
11900
11901 vos_ssr_protect(__func__);
11902 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11903 vos_ssr_unprotect(__func__);
11904
11905 return ret;
11906}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011907
Wilson Yang6507c4e2013-10-01 20:11:19 -070011908
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011909static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011910 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011911{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011912 tANI_U32 j=0;
11913 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011914 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011915 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011916 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011917 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011918 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011919
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011920 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11921 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011922
11923 /* Validate pAdapter */
11924 if (NULL == pAdapter)
11925 {
11926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11927 return -EINVAL;
11928 }
11929
11930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11931 status = wlan_hdd_validate_context(pHddCtx);
11932
11933 if (0 != status)
11934 {
11935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11936 "%s: HDD context is not valid", __func__);
11937 return status;
11938 }
11939
11940 /*Retrieve halHandle*/
11941 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011942 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011943
11944 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011945 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011946 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011947 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11948 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011949 }
11950
11951 /*find the matching PMKSA entry from j=0 to (index-1),
11952 * and delete the matched one
11953 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011954 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011955 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011956 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011957 pmksa->bssid,
11958 WNI_CFG_BSSID_LEN))
11959 {
11960 /* BSSID matched entry */
11961 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011962 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011963 {
11964 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011965 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11966 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11967 VOS_MAC_ADDR_SIZE);
11968 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11969 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11970 CSR_RSN_PMKID_SIZE);
11971 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011972
11973 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011974 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11975 VOS_MAC_ADDR_SIZE);
11976 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11977 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011978 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011979 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011980 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011981 if (eHAL_STATUS_SUCCESS !=
11982 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011983 {
11984 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011985 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011986 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011987 }
11988
11989 dump_bssid(pmksa->bssid);
11990 dump_pmkid(halHandle,pmksa->pmkid);
11991
11992 break;
11993 }
11994 }
11995
11996 /* we compare all entries,but cannot find matching entry */
11997 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
11998 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011999 hddLog(VOS_TRACE_LEVEL_FATAL,
12000 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12001 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012002 dump_bssid(pmksa->bssid);
12003 dump_pmkid(halHandle, pmksa->pmkid);
12004 return -EINVAL;
12005 }
Wilson Yangef657d32014-01-15 19:19:23 -080012006 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012007}
12008
Wilson Yang6507c4e2013-10-01 20:11:19 -070012009
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012010static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12011 struct cfg80211_pmksa *pmksa)
12012{
12013 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012014
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012015 vos_ssr_protect(__func__);
12016 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12017 vos_ssr_unprotect(__func__);
12018
12019 return ret;
12020
12021}
12022
12023static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012024{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012025 tANI_U32 j=0;
12026 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012027 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012028 tHalHandle halHandle;
12029 hdd_context_t *pHddCtx;
12030 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012031 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012032
12033 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12034
12035 /* Validate pAdapter */
12036 if (NULL == pAdapter)
12037 {
12038 hddLog(VOS_TRACE_LEVEL_ERROR,
12039 "%s: Invalid Adapter" ,__func__);
12040 return -EINVAL;
12041 }
12042
12043 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12044 status = wlan_hdd_validate_context(pHddCtx);
12045
12046 if (0 != status)
12047 {
12048 hddLog(VOS_TRACE_LEVEL_ERROR,
12049 "%s: HDD context is not valid", __func__);
12050 return status;
12051 }
12052
12053 /*Retrieve halHandle*/
12054 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012055 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012056
12057 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012058 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012059 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012061 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012062 }
12063
12064 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012065 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012066 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012067 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012068 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012069 if (eHAL_STATUS_SUCCESS !=
12070 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012071 {
12072 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12073 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012074 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012075 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012076 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012077 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12078 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12079 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012080
Agarwal Ashish3da95242014-05-21 14:57:17 +053012081 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012082 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012083}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012084
12085static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12086{
12087 int ret;
12088
12089 vos_ssr_protect(__func__);
12090 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12091 vos_ssr_unprotect(__func__);
12092
12093 return ret;
12094}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012095#endif
12096
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012097#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012098static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12099 struct net_device *dev,
12100 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012101{
12102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12103 hdd_station_ctx_t *pHddStaCtx;
12104
12105 if (NULL == pAdapter)
12106 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012108 return -ENODEV;
12109 }
12110
12111 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12112
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12114 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12115 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012116 // Added for debug on reception of Re-assoc Req.
12117 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12118 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012119 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012120 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012121 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012122 }
12123
12124#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012125 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012126 ftie->ie_len);
12127#endif
12128
12129 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012130 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12131 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012132 ftie->ie_len);
12133 return 0;
12134}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012135
12136static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12137 struct net_device *dev,
12138 struct cfg80211_update_ft_ies_params *ftie)
12139{
12140 int ret;
12141
12142 vos_ssr_protect(__func__);
12143 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12144 vos_ssr_unprotect(__func__);
12145
12146 return ret;
12147}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012148#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012149
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012150#ifdef FEATURE_WLAN_SCAN_PNO
12151
12152void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12153 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12154{
12155 int ret;
12156 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12157 hdd_context_t *pHddCtx;
12158
Nirav Shah80830bf2013-12-31 16:35:12 +053012159 ENTER();
12160
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012161 if (NULL == pAdapter)
12162 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012164 "%s: HDD adapter is Null", __func__);
12165 return ;
12166 }
12167
12168 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12169 if (NULL == pHddCtx)
12170 {
12171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12172 "%s: HDD context is Null!!!", __func__);
12173 return ;
12174 }
12175
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012176 spin_lock(&pHddCtx->schedScan_lock);
12177 if (TRUE == pHddCtx->isWiphySuspended)
12178 {
12179 pHddCtx->isSchedScanUpdatePending = TRUE;
12180 spin_unlock(&pHddCtx->schedScan_lock);
12181 hddLog(VOS_TRACE_LEVEL_INFO,
12182 "%s: Update cfg80211 scan database after it resume", __func__);
12183 return ;
12184 }
12185 spin_unlock(&pHddCtx->schedScan_lock);
12186
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012187 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12188
12189 if (0 > ret)
12190 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12191
12192 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12194 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012195}
12196
12197/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012198 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012199 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012200 */
12201static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12202{
12203 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12204 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012205 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12207 int status = 0;
12208 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12209
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012210 /* The current firmware design does not allow PNO during any
12211 * active sessions. Hence, determine the active sessions
12212 * and return a failure.
12213 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012214 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12215 {
12216 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012217 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012218
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012219 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12220 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12221 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12222 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12223 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12224 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012225 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012226 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012227 }
12228 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12229 pAdapterNode = pNext;
12230 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012231 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012232}
12233
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012234void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12235{
12236 hdd_adapter_t *pAdapter = callbackContext;
12237 hdd_context_t *pHddCtx;
12238
12239 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12240 {
12241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12242 FL("Invalid adapter or adapter has invalid magic"));
12243 return;
12244 }
12245
12246 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12247 if (0 != wlan_hdd_validate_context(pHddCtx))
12248 {
12249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12250 FL("HDD context is not valid"));
12251 return;
12252 }
12253
12254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12255 FL("PNO enable response status = %d"), status);
12256
12257 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12258 complete(&pAdapter->pno_comp_var);
12259}
12260
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012261/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012262 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12263 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012264 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012265static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012266 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12267{
12268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12269 tpSirPNOScanReq pPnoRequest = NULL;
12270 hdd_context_t *pHddCtx;
12271 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012272 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012273 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12274 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012275 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12276 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012277 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012278
12279 if (NULL == pAdapter)
12280 {
Sushant Kaushik10728722014-05-14 16:20:25 +053012281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012282 "%s: HDD adapter is Null", __func__);
12283 return -ENODEV;
12284 }
12285
12286 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012287 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012288
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012289 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012290 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12292 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012293 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012294 }
12295
12296 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12297 if (NULL == hHal)
12298 {
12299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12300 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012301 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012302 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012303
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012304 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012305 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012306 {
12307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12308 "%s: aborting the existing scan is unsuccessfull", __func__);
12309 return -EBUSY;
12310 }
12311
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012312 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012313 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012315 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012316 return -EBUSY;
12317 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012318
c_hpothu37f21312014-04-09 21:49:54 +053012319 if (TRUE == pHddCtx->isPnoEnable)
12320 {
12321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12322 FL("already PNO is enabled"));
12323 return -EBUSY;
12324 }
12325 pHddCtx->isPnoEnable = TRUE;
12326
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012327 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12328 if (NULL == pPnoRequest)
12329 {
12330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12331 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012332 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012333 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012334 }
12335
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012336 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012337 pPnoRequest->enable = 1; /*Enable PNO */
12338 pPnoRequest->ucNetworksCount = request->n_match_sets;
12339
12340 if (( !pPnoRequest->ucNetworksCount ) ||
12341 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12342 {
12343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012344 "%s: Network input is not correct %d Max Network supported is %d",
12345 __func__, pPnoRequest->ucNetworksCount,
12346 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012347 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012348 goto error;
12349 }
12350
12351 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12352 {
12353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012354 "%s: Incorrect number of channels %d",
12355 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012356 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012357 goto error;
12358 }
12359
12360 /* Framework provides one set of channels(all)
12361 * common for all saved profile */
12362 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12363 channels_allowed, &num_channels_allowed))
12364 {
12365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12366 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012367 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012368 goto error;
12369 }
12370 /* Checking each channel against allowed channel list */
12371 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012372 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012373 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012374 char chList [(request->n_channels*5)+1];
12375 int len;
12376 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012377 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012378 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012379 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012380 if (request->channels[i]->hw_value == channels_allowed[indx])
12381 {
12382 valid_ch[num_ch++] = request->channels[i]->hw_value;
12383 len += snprintf(chList+len, 5, "%d ",
12384 request->channels[i]->hw_value);
12385 break ;
12386 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012387 }
12388 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012389 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12390 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012391
12392 /* Filling per profile params */
12393 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12394 {
12395 pPnoRequest->aNetworks[i].ssId.length =
12396 request->match_sets[i].ssid.ssid_len;
12397
12398 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12399 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12400 {
12401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012402 "%s: SSID Len %d is not correct for network %d",
12403 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012404 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012405 goto error;
12406 }
12407
12408 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12409 request->match_sets[i].ssid.ssid,
12410 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12412 "%s: SSID of network %d is %s ", __func__,
12413 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012414 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12415 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12416 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12417
12418 /*Copying list of valid channel into request */
12419 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12420 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12421
12422 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12423 }
12424
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012426 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012427 if ((0 < request->ie_len) && (NULL != request->ie))
12428 {
12429 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12430 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12431 pPnoRequest->us24GProbeTemplateLen);
12432
12433 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12434 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12435 pPnoRequest->us5GProbeTemplateLen);
12436 }
12437
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012438 /* Driver gets only one time interval which is hardcoded in
12439 * supplicant for 10000ms. Taking power consumption into account 6 timers
12440 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12441 * 80,160,320 secs. And number of scan cycle for each timer
12442 * is configurable through INI param gPNOScanTimerRepeatValue.
12443 * If it is set to 0 only one timer will be used and PNO scan cycle
12444 * will be repeated after each interval specified by supplicant
12445 * till PNO is disabled.
12446 */
12447 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12448 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12449 else
12450 pPnoRequest->scanTimers.ucScanTimersCount =
12451 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12452
12453 tempInterval = (request->interval)/1000;
12454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12455 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12456 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12457 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12458 {
12459 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12460 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12461 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12462 tempInterval *= 2;
12463 }
12464 //Repeat last timer until pno disabled.
12465 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12466
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012467 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012468
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012469 INIT_COMPLETION(pAdapter->pno_comp_var);
12470 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12471 pPnoRequest->callbackContext = pAdapter;
12472 pAdapter->pno_req_status = 0;
12473
Nirav Shah80830bf2013-12-31 16:35:12 +053012474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12475 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12476 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12477 pPnoRequest->scanTimers.ucScanTimersCount);
12478
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012479 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12480 pPnoRequest, pAdapter->sessionId,
12481 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12482 if (eHAL_STATUS_SUCCESS != status)
12483 {
12484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012485 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012486 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012487 goto error;
12488 }
12489
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012490 ret = wait_for_completion_timeout(
12491 &pAdapter->pno_comp_var,
12492 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12493 if (0 >= ret)
12494 {
12495 // Did not receive the response for PNO enable in time.
12496 // Assuming the PNO enable was success.
12497 // Returning error from here, because we timeout, results
12498 // in side effect of Wifi (Wifi Setting) not to work.
12499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12500 FL("Timed out waiting for PNO to be Enabled"));
12501 ret = 0;
12502 goto error;
12503 }
12504
12505 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012506 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012507
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012508error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12510 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012511 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012512 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012513 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012514}
12515
12516/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012517 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12518 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012519 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012520static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12521 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12522{
12523 int ret;
12524
12525 vos_ssr_protect(__func__);
12526 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12527 vos_ssr_unprotect(__func__);
12528
12529 return ret;
12530}
12531
12532/*
12533 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12534 * Function to disable PNO
12535 */
12536static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012537 struct net_device *dev)
12538{
12539 eHalStatus status = eHAL_STATUS_FAILURE;
12540 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12541 hdd_context_t *pHddCtx;
12542 tHalHandle hHal;
12543 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012544 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012545
12546 ENTER();
12547
12548 if (NULL == pAdapter)
12549 {
Sushant Kaushik10728722014-05-14 16:20:25 +053012550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012551 "%s: HDD adapter is Null", __func__);
12552 return -ENODEV;
12553 }
12554
12555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012556
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012557 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012558 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012560 "%s: HDD context is Null", __func__);
12561 return -ENODEV;
12562 }
12563
12564 /* The return 0 is intentional when isLogpInProgress and
12565 * isLoadUnloadInProgress. We did observe a crash due to a return of
12566 * failure in sched_scan_stop , especially for a case where the unload
12567 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12568 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12569 * success. If it returns a failure , then its next invocation due to the
12570 * clean up of the second interface will have the dev pointer corresponding
12571 * to the first one leading to a crash.
12572 */
12573 if (pHddCtx->isLogpInProgress)
12574 {
12575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12576 "%s: LOGP in Progress. Ignore!!!", __func__);
12577 return ret;
12578 }
12579
Mihir Shete18156292014-03-11 15:38:30 +053012580 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012581 {
12582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12583 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12584 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012585 }
12586
12587 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12588 if (NULL == hHal)
12589 {
12590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12591 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012592 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012593 }
12594
12595 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12596 if (NULL == pPnoRequest)
12597 {
12598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12599 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012600 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012601 }
12602
12603 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12604 pPnoRequest->enable = 0; /* Disable PNO */
12605 pPnoRequest->ucNetworksCount = 0;
12606
12607 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12608 pAdapter->sessionId,
12609 NULL, pAdapter);
12610 if (eHAL_STATUS_SUCCESS != status)
12611 {
12612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12613 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012614 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012615 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012616 }
c_hpothu37f21312014-04-09 21:49:54 +053012617 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012618
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012619error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012621 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012622 vos_mem_free(pPnoRequest);
12623
12624 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012625 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012626}
12627
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012628/*
12629 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12630 * NL interface to disable PNO
12631 */
12632static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12633 struct net_device *dev)
12634{
12635 int ret;
12636
12637 vos_ssr_protect(__func__);
12638 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12639 vos_ssr_unprotect(__func__);
12640
12641 return ret;
12642}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012643#endif /*FEATURE_WLAN_SCAN_PNO*/
12644
12645
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012646#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012647#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012648static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12649 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012650 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12651#else
12652static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12653 u8 *peer, u8 action_code, u8 dialog_token,
12654 u16 status_code, const u8 *buf, size_t len)
12655#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012656{
12657
12658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012660 u8 peerMac[6];
12661 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012662 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012663 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012664 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012665#if !(TDLS_MGMT_VERSION2)
12666 u32 peer_capability = 0;
12667#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012668 tANI_U16 numCurrTdlsPeers;
Sushant Kaushik10728722014-05-14 16:20:25 +053012669 if (NULL == pAdapter)
12670 {
12671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12672 "%s: HDD adapter context is Null", __func__);
12673 return -ENODEV;
12674 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012675 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12676 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12677 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012678 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012681 "Invalid arguments");
12682 return -EINVAL;
12683 }
12684
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012685 if (pHddCtx->isLogpInProgress)
12686 {
12687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12688 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012689 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012690 return -EBUSY;
12691 }
12692
Hoonki Lee27511902013-03-14 18:19:06 -070012693 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012694 {
Hoonki Lee27511902013-03-14 18:19:06 -070012695 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12696 "%s: TDLS mode is disabled OR not enabled in FW."
12697 MAC_ADDRESS_STR " action %d declined.",
12698 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012699 return -ENOTSUPP;
12700 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012701
Hoonki Lee27511902013-03-14 18:19:06 -070012702 /* other than teardown frame, other mgmt frames are not sent if disabled */
12703 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12704 {
12705 /* if tdls_mode is disabled to respond to peer's request */
12706 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12707 {
12708 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12709 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012710 " TDLS mode is disabled. action %d declined.",
12711 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012712
12713 return -ENOTSUPP;
12714 }
12715 }
12716
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012717 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12718 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012719 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012720 {
12721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012722 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012723 " TDLS setup is ongoing. action %d declined.",
12724 __func__, MAC_ADDR_ARRAY(peer), action_code);
12725 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012726 }
12727 }
12728
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012729 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12730 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012731 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012732 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12733 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012734 {
12735 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12736 we return error code at 'add_station()'. Hence we have this
12737 check again in addtion to add_station().
12738 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012739 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012740 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12742 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012743 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12744 __func__, MAC_ADDR_ARRAY(peer), action_code,
12745 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012746 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012747 }
12748 else
12749 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012750 /* maximum reached. tweak to send error code to peer and return
12751 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012752 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12754 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012755 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12756 __func__, MAC_ADDR_ARRAY(peer), status_code,
12757 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012758 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012759 /* fall through to send setup resp with failure status
12760 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012761 }
12762 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012763 else
12764 {
12765 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012766 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012767 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012768 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012770 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12771 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012772 return -EPERM;
12773 }
12774 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012775 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012776 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012777
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012778#ifdef WLAN_FEATURE_TDLS_DEBUG
12779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012780 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012781 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12782 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012783#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012784
Hoonki Leea34dd892013-02-05 22:56:02 -080012785 /*Except teardown responder will not be used so just make 0*/
12786 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012787 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012788 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012789
12790 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012791 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012792
12793 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12794 responder = pTdlsPeer->is_responder;
12795 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012796 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012798 "%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 -070012799 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12800 dialog_token, status_code, len);
12801 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012802 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012803 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012804
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012805 /* For explicit trigger of DIS_REQ come out of BMPS for
12806 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012807 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012808 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12809 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012810 {
12811 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12812 {
12813 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012814 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012815 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12816 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012817 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12818 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012819 }
12820
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012821 /* make sure doesn't call send_mgmt() while it is pending */
12822 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12823 {
12824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012825 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012826 __func__, MAC_ADDR_ARRAY(peer), action_code);
12827 return -EBUSY;
12828 }
12829
12830 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012831 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12832
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012833 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012834 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012835
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012836 if (VOS_STATUS_SUCCESS != status)
12837 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12839 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012840 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012841 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012842 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012843 }
12844
Hoonki Leed37cbb32013-04-20 00:31:14 -070012845 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12846 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12847
12848 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012849 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012851 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012852 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012853 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012854
12855 if (pHddCtx->isLogpInProgress)
12856 {
12857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12858 "%s: LOGP in Progress. Ignore!!!", __func__);
12859 return -EAGAIN;
12860 }
12861
Hoonki Leed37cbb32013-04-20 00:31:14 -070012862 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012863 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012864 }
12865
Gopichand Nakkala05922802013-03-14 12:23:19 -070012866 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012867 {
12868 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012869 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012870 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012871
Hoonki Leea34dd892013-02-05 22:56:02 -080012872 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12873 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012874 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012875 }
12876 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12877 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012878 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012879 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012880
12881 return 0;
12882}
12883
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012884static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012885 u8 *peer, enum nl80211_tdls_operation oper)
12886{
12887 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12888 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012889 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012890 hddTdlsPeer_t *pTdlsPeer;
Sushant Kaushik10728722014-05-14 16:20:25 +053012891 if (NULL == pAdapter)
12892 {
12893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12894 "%s: HDD adapter context is Null", __func__);
12895 return -ENODEV;
12896 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12898 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12899 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012900 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012901 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012903 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012904 return -EINVAL;
12905 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012906
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012907 status = wlan_hdd_validate_context(pHddCtx);
12908
12909 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12912 "%s: HDD context is not valid", __func__);
12913 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012914 }
12915
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012916
12917 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012918 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012919 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012921 "TDLS Disabled in INI OR not enabled in FW. "
12922 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012923 return -ENOTSUPP;
12924 }
12925
12926 switch (oper) {
12927 case NL80211_TDLS_ENABLE_LINK:
12928 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012929 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012930 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012931 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012932
Sunil Dutt41de4e22013-11-14 18:09:02 +053012933 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12934
12935 if ( NULL == pTdlsPeer ) {
12936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12937 " (oper %d) not exsting. ignored",
12938 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12939 return -EINVAL;
12940 }
12941
12942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12943 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12944 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12945 "NL80211_TDLS_ENABLE_LINK");
12946
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012947 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12948 {
12949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12950 MAC_ADDRESS_STR " failed",
12951 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12952 return -EINVAL;
12953 }
12954
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012955 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012956 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012957 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012958
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012959 if (0 != wlan_hdd_tdls_get_link_establish_params(
12960 pAdapter, peer,&tdlsLinkEstablishParams)) {
12961 return -EINVAL;
12962 }
12963 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012964
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012965 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12966 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12967 /* Send TDLS peer UAPSD capabilities to the firmware and
12968 * register with the TL on after the response for this operation
12969 * is received .
12970 */
12971 ret = wait_for_completion_interruptible_timeout(
12972 &pAdapter->tdls_link_establish_req_comp,
12973 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12974 if (ret <= 0)
12975 {
12976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12977 "%s: Link Establish Request Faled Status %ld",
12978 __func__, ret);
12979 return -EINVAL;
12980 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012981 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012982 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012983 /* Mark TDLS client Authenticated .*/
12984 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12985 pTdlsPeer->staId,
12986 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012987 if (VOS_STATUS_SUCCESS == status)
12988 {
Hoonki Lee14621352013-04-16 17:51:19 -070012989 if (pTdlsPeer->is_responder == 0)
12990 {
12991 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
12992
12993 wlan_hdd_tdls_timer_restart(pAdapter,
12994 &pTdlsPeer->initiatorWaitTimeoutTimer,
12995 WAIT_TIME_TDLS_INITIATOR);
12996 /* suspend initiator TX until it receives direct packet from the
12997 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
12998 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12999 &staId, NULL);
13000 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013001 wlan_hdd_tdls_increment_peer_count(pAdapter);
13002 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013003 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013004
13005 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013006 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13007 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013008 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013009 int ac;
13010 uint8 ucAc[4] = { WLANTL_AC_VO,
13011 WLANTL_AC_VI,
13012 WLANTL_AC_BK,
13013 WLANTL_AC_BE };
13014 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13015 for(ac=0; ac < 4; ac++)
13016 {
13017 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13018 pTdlsPeer->staId, ucAc[ac],
13019 tlTid[ac], tlTid[ac], 0, 0,
13020 WLANTL_BI_DIR );
13021 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013022 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013023 }
13024
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013025 }
13026 break;
13027 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013028 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013029 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13030
13031 if ( NULL == pTdlsPeer ) {
13032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13033 " (oper %d) not exsting. ignored",
13034 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13035 return -EINVAL;
13036 }
13037
13038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13039 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13040 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13041 "NL80211_TDLS_DISABLE_LINK");
13042
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013043 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013044 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013045 long status;
13046
13047 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13048
Lee Hoonkic1262f22013-01-24 21:59:00 -080013049 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13050 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013051
13052 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13053 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13054 if (status <= 0)
13055 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013056 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13058 "%s: Del station failed status %ld",
13059 __func__, status);
13060 return -EPERM;
13061 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013062 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013063 }
13064 else
13065 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13067 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013068 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013069 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013070 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013071 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013072 {
13073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13074 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13075 __func__, MAC_ADDR_ARRAY(peer));
13076
13077 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13078 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13079
13080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13081 " %s TDLS External control and Implicit Trigger not enabled ",
13082 __func__);
13083 return -ENOTSUPP;
13084 }
13085
Sunil Dutt41de4e22013-11-14 18:09:02 +053013086
13087 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13088
13089 if ( NULL == pTdlsPeer ) {
13090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13091 " peer not exsting",
13092 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013093 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013094 }
13095 else {
13096 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13097 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13098 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013099
13100 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13101 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013102 break;
13103 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013104 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013105 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013106 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13108 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13109 __func__, MAC_ADDR_ARRAY(peer));
13110
13111 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13112 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13113
13114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13115 " %s TDLS External control and Implicit Trigger not enabled ",
13116 __func__);
13117 return -ENOTSUPP;
13118 }
13119
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013120 /* To cater the requirement of establishing the TDLS link
13121 * irrespective of the data traffic , get an entry of TDLS peer.
13122 */
13123 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13124 if (pTdlsPeer == NULL) {
13125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13126 "%s: peer " MAC_ADDRESS_STR " not existing",
13127 __func__, MAC_ADDR_ARRAY(peer));
13128 return -EINVAL;
13129 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013130
13131 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13132
13133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13134 " %s TDLS Add Force Peer Failed",
13135 __func__);
13136 return -EINVAL;
13137 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013138 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013139 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013140 case NL80211_TDLS_DISCOVERY_REQ:
13141 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13143 "%s: We don't support in-driver setup/teardown/discovery "
13144 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013145 return -ENOTSUPP;
13146 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13148 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013149 return -ENOTSUPP;
13150 }
13151 return 0;
13152}
Chilam NG571c65a2013-01-19 12:27:36 +053013153
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013154static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13155 u8 *peer, enum nl80211_tdls_operation oper)
13156{
13157 int ret;
13158
13159 vos_ssr_protect(__func__);
13160 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13161 vos_ssr_unprotect(__func__);
13162
13163 return ret;
13164}
13165
Chilam NG571c65a2013-01-19 12:27:36 +053013166int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13167 struct net_device *dev, u8 *peer)
13168{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013169 hddLog(VOS_TRACE_LEVEL_INFO,
13170 "tdls send discover req: "MAC_ADDRESS_STR,
13171 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013172
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013173#if TDLS_MGMT_VERSION2
13174 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13175 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13176#else
Chilam NG571c65a2013-01-19 12:27:36 +053013177 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13178 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013179#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013180}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013181#endif
13182
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013183#ifdef WLAN_FEATURE_GTK_OFFLOAD
13184/*
13185 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13186 * Callback rountine called upon receiving response for
13187 * get offload info
13188 */
13189void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13190 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13191{
13192
13193 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013194 tANI_U8 tempReplayCounter[8];
13195 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013196
13197 ENTER();
13198
13199 if (NULL == pAdapter)
13200 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013202 "%s: HDD adapter is Null", __func__);
13203 return ;
13204 }
13205
13206 if (NULL == pGtkOffloadGetInfoRsp)
13207 {
13208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13209 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13210 return ;
13211 }
13212
13213 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13214 {
13215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13216 "%s: wlan Failed to get replay counter value",
13217 __func__);
13218 return ;
13219 }
13220
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013221 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13222 /* Update replay counter */
13223 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13224 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13225
13226 {
13227 /* changing from little to big endian since supplicant
13228 * works on big endian format
13229 */
13230 int i;
13231 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13232
13233 for (i = 0; i < 8; i++)
13234 {
13235 tempReplayCounter[7-i] = (tANI_U8)p[i];
13236 }
13237 }
13238
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013239 /* Update replay counter to NL */
13240 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013241 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013242}
13243
13244/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013245 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013246 * This function is used to offload GTK rekeying job to the firmware.
13247 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013248int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013249 struct cfg80211_gtk_rekey_data *data)
13250{
13251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13253 hdd_station_ctx_t *pHddStaCtx;
13254 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013255 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013256 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013257 eHalStatus status = eHAL_STATUS_FAILURE;
13258
13259 ENTER();
13260
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013261
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013262 if (NULL == pAdapter)
13263 {
Sushant Kaushik10728722014-05-14 16:20:25 +053013264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013265 "%s: HDD adapter is Null", __func__);
13266 return -ENODEV;
13267 }
13268
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013269 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13270 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13271 pAdapter->sessionId, pAdapter->device_mode));
13272
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013273 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013274
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013275 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013276 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13278 "%s: HDD context is not valid", __func__);
13279 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013280 }
13281
13282 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13283 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13284 if (NULL == hHal)
13285 {
13286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13287 "%s: HAL context is Null!!!", __func__);
13288 return -EAGAIN;
13289 }
13290
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013291 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13292 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13293 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13294 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013295 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013296 {
13297 /* changing from big to little endian since driver
13298 * works on little endian format
13299 */
13300 tANI_U8 *p =
13301 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13302 int i;
13303
13304 for (i = 0; i < 8; i++)
13305 {
13306 p[7-i] = data->replay_ctr[i];
13307 }
13308 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013309
13310 if (TRUE == pHddCtx->hdd_wlan_suspended)
13311 {
13312 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013313 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13314 sizeof (tSirGtkOffloadParams));
13315 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013316 pAdapter->sessionId);
13317
13318 if (eHAL_STATUS_SUCCESS != status)
13319 {
13320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13321 "%s: sme_SetGTKOffload failed, returned %d",
13322 __func__, status);
13323 return status;
13324 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13326 "%s: sme_SetGTKOffload successfull", __func__);
13327 }
13328 else
13329 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13331 "%s: wlan not suspended GTKOffload request is stored",
13332 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013333 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013334
13335 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013336}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013337
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013338int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13339 struct cfg80211_gtk_rekey_data *data)
13340{
13341 int ret;
13342
13343 vos_ssr_protect(__func__);
13344 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13345 vos_ssr_unprotect(__func__);
13346
13347 return ret;
13348}
13349#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013350/*
13351 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13352 * This function is used to set access control policy
13353 */
13354static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13355 struct net_device *dev, const struct cfg80211_acl_data *params)
13356{
13357 int i;
13358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13359 hdd_hostapd_state_t *pHostapdState;
13360 tsap_Config_t *pConfig;
13361 v_CONTEXT_t pVosContext = NULL;
13362 hdd_context_t *pHddCtx;
13363 int status;
13364
13365 ENTER();
13366
13367 if (NULL == pAdapter)
13368 {
13369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13370 "%s: HDD adapter is Null", __func__);
13371 return -ENODEV;
13372 }
13373
13374 if (NULL == params)
13375 {
13376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13377 "%s: params is Null", __func__);
13378 return -EINVAL;
13379 }
13380
13381 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13382 status = wlan_hdd_validate_context(pHddCtx);
13383
13384 if (0 != status)
13385 {
13386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13387 "%s: HDD context is not valid", __func__);
13388 return status;
13389 }
13390
13391 pVosContext = pHddCtx->pvosContext;
13392 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13393
13394 if (NULL == pHostapdState)
13395 {
13396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13397 "%s: pHostapdState is Null", __func__);
13398 return -EINVAL;
13399 }
13400
13401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13402 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13403
13404 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13405 {
13406 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13407
13408 /* default value */
13409 pConfig->num_accept_mac = 0;
13410 pConfig->num_deny_mac = 0;
13411
13412 /**
13413 * access control policy
13414 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13415 * listed in hostapd.deny file.
13416 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13417 * listed in hostapd.accept file.
13418 */
13419 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13420 {
13421 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13422 }
13423 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13424 {
13425 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13426 }
13427 else
13428 {
13429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13430 "%s:Acl Policy : %d is not supported",
13431 __func__, params->acl_policy);
13432 return -ENOTSUPP;
13433 }
13434
13435 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13436 {
13437 pConfig->num_accept_mac = params->n_acl_entries;
13438 for (i = 0; i < params->n_acl_entries; i++)
13439 {
13440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13441 "** Add ACL MAC entry %i in WhiletList :"
13442 MAC_ADDRESS_STR, i,
13443 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13444
13445 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13446 sizeof(qcmacaddr));
13447 }
13448 }
13449 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13450 {
13451 pConfig->num_deny_mac = params->n_acl_entries;
13452 for (i = 0; i < params->n_acl_entries; i++)
13453 {
13454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13455 "** Add ACL MAC entry %i in BlackList :"
13456 MAC_ADDRESS_STR, i,
13457 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13458
13459 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13460 sizeof(qcmacaddr));
13461 }
13462 }
13463
13464 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13465 {
13466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13467 "%s: SAP Set Mac Acl fail", __func__);
13468 return -EINVAL;
13469 }
13470 }
13471 else
13472 {
13473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013474 "%s: Invalid device_mode = %s (%d)",
13475 __func__, hdd_device_modetoString(pAdapter->device_mode),
13476 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013477 return -EINVAL;
13478 }
13479
13480 return 0;
13481}
13482
Leo Chang9056f462013-08-01 19:21:11 -070013483#ifdef WLAN_NL80211_TESTMODE
13484#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013485void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013486(
13487 void *pAdapter,
13488 void *indCont
13489)
13490{
Leo Changd9df8aa2013-09-26 13:32:26 -070013491 tSirLPHBInd *lphbInd;
13492 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013493 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013494
13495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013496 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013497
c_hpothu73f35e62014-04-18 13:40:08 +053013498 if (pAdapter == NULL)
13499 {
13500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13501 "%s: pAdapter is NULL\n",__func__);
13502 return;
13503 }
13504
Leo Chang9056f462013-08-01 19:21:11 -070013505 if (NULL == indCont)
13506 {
13507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013508 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013509 return;
13510 }
13511
c_hpothu73f35e62014-04-18 13:40:08 +053013512 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013513 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013514 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013515 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013516 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013517 GFP_ATOMIC);
13518 if (!skb)
13519 {
13520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13521 "LPHB timeout, NL buffer alloc fail");
13522 return;
13523 }
13524
Leo Changac3ba772013-10-07 09:47:04 -070013525 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013526 {
13527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13528 "WLAN_HDD_TM_ATTR_CMD put fail");
13529 goto nla_put_failure;
13530 }
Leo Changac3ba772013-10-07 09:47:04 -070013531 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013532 {
13533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13534 "WLAN_HDD_TM_ATTR_TYPE put fail");
13535 goto nla_put_failure;
13536 }
Leo Changac3ba772013-10-07 09:47:04 -070013537 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013538 sizeof(tSirLPHBInd), lphbInd))
13539 {
13540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13541 "WLAN_HDD_TM_ATTR_DATA put fail");
13542 goto nla_put_failure;
13543 }
Leo Chang9056f462013-08-01 19:21:11 -070013544 cfg80211_testmode_event(skb, GFP_ATOMIC);
13545 return;
13546
13547nla_put_failure:
13548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13549 "NLA Put fail");
13550 kfree_skb(skb);
13551
13552 return;
13553}
13554#endif /* FEATURE_WLAN_LPHB */
13555
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013556static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013557{
13558 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13559 int err = 0;
13560#ifdef FEATURE_WLAN_LPHB
13561 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013562 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013563#endif /* FEATURE_WLAN_LPHB */
13564
13565 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13566 if (err)
13567 {
13568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13569 "%s Testmode INV ATTR", __func__);
13570 return err;
13571 }
13572
13573 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13574 {
13575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13576 "%s Testmode INV CMD", __func__);
13577 return -EINVAL;
13578 }
13579
13580 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13581 {
13582#ifdef FEATURE_WLAN_LPHB
13583 /* Low Power Heartbeat configuration request */
13584 case WLAN_HDD_TM_CMD_WLAN_HB:
13585 {
13586 int buf_len;
13587 void *buf;
13588 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013589 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013590
13591 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13592 {
13593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13594 "%s Testmode INV DATA", __func__);
13595 return -EINVAL;
13596 }
13597
13598 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13599 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013600
13601 hb_params_temp =(tSirLPHBReq *)buf;
13602 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13603 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13604 return -EINVAL;
13605
Leo Chang9056f462013-08-01 19:21:11 -070013606 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13607 if (NULL == hb_params)
13608 {
13609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13610 "%s Request Buffer Alloc Fail", __func__);
13611 return -EINVAL;
13612 }
13613
13614 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013615 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13616 hb_params,
13617 wlan_hdd_cfg80211_lphb_ind_handler);
13618 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013619 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13621 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013622 vos_mem_free(hb_params);
13623 }
Leo Chang9056f462013-08-01 19:21:11 -070013624 return 0;
13625 }
13626#endif /* FEATURE_WLAN_LPHB */
13627 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13629 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013630 return -EOPNOTSUPP;
13631 }
13632
13633 return err;
13634}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013635
13636static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13637{
13638 int ret;
13639
13640 vos_ssr_protect(__func__);
13641 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13642 vos_ssr_unprotect(__func__);
13643
13644 return ret;
13645}
Leo Chang9056f462013-08-01 19:21:11 -070013646#endif /* CONFIG_NL80211_TESTMODE */
13647
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013648static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013649 struct net_device *dev,
13650 int idx, struct survey_info *survey)
13651{
13652 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13653 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013654 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013655 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013656 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013657 v_S7_t snr,rssi;
13658 int status, i, j, filled = 0;
13659
13660 ENTER();
13661
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013662 if (NULL == pAdapter)
13663 {
13664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13665 "%s: HDD adapter is Null", __func__);
13666 return -ENODEV;
13667 }
13668
13669 if (NULL == wiphy)
13670 {
13671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13672 "%s: wiphy is Null", __func__);
13673 return -ENODEV;
13674 }
13675
13676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13677 status = wlan_hdd_validate_context(pHddCtx);
13678
13679 if (0 != status)
13680 {
13681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13682 "%s: HDD context is not valid", __func__);
13683 return status;
13684 }
13685
Mihir Sheted9072e02013-08-21 17:02:29 +053013686 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13687
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013688 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013689 0 != pAdapter->survey_idx ||
13690 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013691 {
13692 /* The survey dump ops when implemented completely is expected to
13693 * return a survey of all channels and the ops is called by the
13694 * kernel with incremental values of the argument 'idx' till it
13695 * returns -ENONET. But we can only support the survey for the
13696 * operating channel for now. survey_idx is used to track
13697 * that the ops is called only once and then return -ENONET for
13698 * the next iteration
13699 */
13700 pAdapter->survey_idx = 0;
13701 return -ENONET;
13702 }
13703
13704 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13705
13706 wlan_hdd_get_snr(pAdapter, &snr);
13707 wlan_hdd_get_rssi(pAdapter, &rssi);
13708
13709 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13710 hdd_wlan_get_freq(channel, &freq);
13711
13712
13713 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13714 {
13715 if (NULL == wiphy->bands[i])
13716 {
13717 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13718 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13719 continue;
13720 }
13721
13722 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13723 {
13724 struct ieee80211_supported_band *band = wiphy->bands[i];
13725
13726 if (band->channels[j].center_freq == (v_U16_t)freq)
13727 {
13728 survey->channel = &band->channels[j];
13729 /* The Rx BDs contain SNR values in dB for the received frames
13730 * while the supplicant expects noise. So we calculate and
13731 * return the value of noise (dBm)
13732 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13733 */
13734 survey->noise = rssi - snr;
13735 survey->filled = SURVEY_INFO_NOISE_DBM;
13736 filled = 1;
13737 }
13738 }
13739 }
13740
13741 if (filled)
13742 pAdapter->survey_idx = 1;
13743 else
13744 {
13745 pAdapter->survey_idx = 0;
13746 return -ENONET;
13747 }
13748
13749 return 0;
13750}
13751
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013752static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13753 struct net_device *dev,
13754 int idx, struct survey_info *survey)
13755{
13756 int ret;
13757
13758 vos_ssr_protect(__func__);
13759 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13760 vos_ssr_unprotect(__func__);
13761
13762 return ret;
13763}
13764
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013765/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013766 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013767 * this is called when cfg80211 driver resume
13768 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13769 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013770int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013771{
13772 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13773 hdd_adapter_t *pAdapter;
13774 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13775 VOS_STATUS status = VOS_STATUS_SUCCESS;
13776
13777 ENTER();
13778
13779 if ( NULL == pHddCtx )
13780 {
13781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13782 "%s: HddCtx validation failed", __func__);
13783 return 0;
13784 }
13785
13786 if (pHddCtx->isLogpInProgress)
13787 {
13788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13789 "%s: LOGP in Progress. Ignore!!!", __func__);
13790 return 0;
13791 }
13792
Mihir Shete18156292014-03-11 15:38:30 +053013793 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013794 {
13795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13796 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13797 return 0;
13798 }
13799
13800 spin_lock(&pHddCtx->schedScan_lock);
13801 pHddCtx->isWiphySuspended = FALSE;
13802 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13803 {
13804 spin_unlock(&pHddCtx->schedScan_lock);
13805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13806 "%s: Return resume is not due to PNO indication", __func__);
13807 return 0;
13808 }
13809 // Reset flag to avoid updatating cfg80211 data old results again
13810 pHddCtx->isSchedScanUpdatePending = FALSE;
13811 spin_unlock(&pHddCtx->schedScan_lock);
13812
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013813
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013814 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13815
13816 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13817 {
13818 pAdapter = pAdapterNode->pAdapter;
13819 if ( (NULL != pAdapter) &&
13820 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13821 {
13822 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013823 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13825 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013826 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013827 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013828 {
13829 /* Acquire wakelock to handle the case where APP's tries to
13830 * suspend immediately after updating the scan results. Whis
13831 * results in app's is in suspended state and not able to
13832 * process the connect request to AP
13833 */
13834 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013835 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013836 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013837
13838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13839 "%s : cfg80211 scan result database updated", __func__);
13840
13841 return 0;
13842
13843 }
13844 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13845 pAdapterNode = pNext;
13846 }
13847
13848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13849 "%s: Failed to find Adapter", __func__);
13850 return 0;
13851}
13852
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013853int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13854{
13855 int ret;
13856
13857 vos_ssr_protect(__func__);
13858 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13859 vos_ssr_unprotect(__func__);
13860
13861 return ret;
13862}
13863
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013864/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013865 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013866 * this is called when cfg80211 driver suspends
13867 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013868int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013869 struct cfg80211_wowlan *wow)
13870{
13871 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13872
13873 ENTER();
13874 if (NULL == pHddCtx)
13875 {
13876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13877 "%s: HddCtx validation failed", __func__);
13878 return 0;
13879 }
13880
13881 pHddCtx->isWiphySuspended = TRUE;
13882
13883 EXIT();
13884
13885 return 0;
13886}
13887
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013888int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13889 struct cfg80211_wowlan *wow)
13890{
13891 int ret;
13892
13893 vos_ssr_protect(__func__);
13894 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13895 vos_ssr_unprotect(__func__);
13896
13897 return ret;
13898}
Jeff Johnson295189b2012-06-20 16:38:30 -070013899/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013900static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013901{
13902 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13903 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13904 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13905 .change_station = wlan_hdd_change_station,
13906#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13907 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13908 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13909 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013910#else
13911 .start_ap = wlan_hdd_cfg80211_start_ap,
13912 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13913 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013914#endif
13915 .change_bss = wlan_hdd_cfg80211_change_bss,
13916 .add_key = wlan_hdd_cfg80211_add_key,
13917 .get_key = wlan_hdd_cfg80211_get_key,
13918 .del_key = wlan_hdd_cfg80211_del_key,
13919 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013920#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013922#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013923 .scan = wlan_hdd_cfg80211_scan,
13924 .connect = wlan_hdd_cfg80211_connect,
13925 .disconnect = wlan_hdd_cfg80211_disconnect,
13926 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13927 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13928 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13929 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13930 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13932 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013933 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13935 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13936 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13937 .set_txq_params = wlan_hdd_set_txq_params,
13938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013939 .get_station = wlan_hdd_cfg80211_get_station,
13940 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13941 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013942 .add_station = wlan_hdd_cfg80211_add_station,
13943#ifdef FEATURE_WLAN_LFR
13944 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13945 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13946 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13947#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013948#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13949 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13950#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013951#ifdef FEATURE_WLAN_TDLS
13952 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13953 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13954#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013955#ifdef WLAN_FEATURE_GTK_OFFLOAD
13956 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13957#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013958#ifdef FEATURE_WLAN_SCAN_PNO
13959 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13960 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13961#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013962 .resume = wlan_hdd_cfg80211_resume_wlan,
13963 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013964 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013965#ifdef WLAN_NL80211_TESTMODE
13966 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13967#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013968 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013969};
13970