blob: 5e4b84916144df22a4b99dce7e8cb72e0af0c6d8 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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 Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
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"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530176static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700177{
178 WLAN_CIPHER_SUITE_WEP40,
179 WLAN_CIPHER_SUITE_WEP104,
180 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700182#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
183 WLAN_CIPHER_SUITE_KRK,
184 WLAN_CIPHER_SUITE_CCMP,
185#else
186 WLAN_CIPHER_SUITE_CCMP,
187#endif
188#ifdef FEATURE_WLAN_WAPI
189 WLAN_CIPHER_SUITE_SMS4,
190#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700191#ifdef WLAN_FEATURE_11W
192 WLAN_CIPHER_SUITE_AES_CMAC,
193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700194};
195
196static inline int is_broadcast_ether_addr(const u8 *addr)
197{
198 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
199 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
200}
201
202static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530203{
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 HDD2GHZCHAN(2412, 1, 0) ,
205 HDD2GHZCHAN(2417, 2, 0) ,
206 HDD2GHZCHAN(2422, 3, 0) ,
207 HDD2GHZCHAN(2427, 4, 0) ,
208 HDD2GHZCHAN(2432, 5, 0) ,
209 HDD2GHZCHAN(2437, 6, 0) ,
210 HDD2GHZCHAN(2442, 7, 0) ,
211 HDD2GHZCHAN(2447, 8, 0) ,
212 HDD2GHZCHAN(2452, 9, 0) ,
213 HDD2GHZCHAN(2457, 10, 0) ,
214 HDD2GHZCHAN(2462, 11, 0) ,
215 HDD2GHZCHAN(2467, 12, 0) ,
216 HDD2GHZCHAN(2472, 13, 0) ,
217 HDD2GHZCHAN(2484, 14, 0) ,
218};
219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
221{
222 HDD2GHZCHAN(2412, 1, 0) ,
223 HDD2GHZCHAN(2437, 6, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225};
Jeff Johnson295189b2012-06-20 16:38:30 -0700226
227static struct ieee80211_channel hdd_channels_5_GHZ[] =
228{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700229 HDD5GHZCHAN(4920, 240, 0) ,
230 HDD5GHZCHAN(4940, 244, 0) ,
231 HDD5GHZCHAN(4960, 248, 0) ,
232 HDD5GHZCHAN(4980, 252, 0) ,
233 HDD5GHZCHAN(5040, 208, 0) ,
234 HDD5GHZCHAN(5060, 212, 0) ,
235 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 HDD5GHZCHAN(5180, 36, 0) ,
237 HDD5GHZCHAN(5200, 40, 0) ,
238 HDD5GHZCHAN(5220, 44, 0) ,
239 HDD5GHZCHAN(5240, 48, 0) ,
240 HDD5GHZCHAN(5260, 52, 0) ,
241 HDD5GHZCHAN(5280, 56, 0) ,
242 HDD5GHZCHAN(5300, 60, 0) ,
243 HDD5GHZCHAN(5320, 64, 0) ,
244 HDD5GHZCHAN(5500,100, 0) ,
245 HDD5GHZCHAN(5520,104, 0) ,
246 HDD5GHZCHAN(5540,108, 0) ,
247 HDD5GHZCHAN(5560,112, 0) ,
248 HDD5GHZCHAN(5580,116, 0) ,
249 HDD5GHZCHAN(5600,120, 0) ,
250 HDD5GHZCHAN(5620,124, 0) ,
251 HDD5GHZCHAN(5640,128, 0) ,
252 HDD5GHZCHAN(5660,132, 0) ,
253 HDD5GHZCHAN(5680,136, 0) ,
254 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800255#ifdef FEATURE_WLAN_CH144
256 HDD5GHZCHAN(5720,144, 0) ,
257#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 HDD5GHZCHAN(5745,149, 0) ,
259 HDD5GHZCHAN(5765,153, 0) ,
260 HDD5GHZCHAN(5785,157, 0) ,
261 HDD5GHZCHAN(5805,161, 0) ,
262 HDD5GHZCHAN(5825,165, 0) ,
263};
264
265static struct ieee80211_rate g_mode_rates[] =
266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530267 HDD_G_MODE_RATETAB(10, 0x1, 0),
268 HDD_G_MODE_RATETAB(20, 0x2, 0),
269 HDD_G_MODE_RATETAB(55, 0x4, 0),
270 HDD_G_MODE_RATETAB(110, 0x8, 0),
271 HDD_G_MODE_RATETAB(60, 0x10, 0),
272 HDD_G_MODE_RATETAB(90, 0x20, 0),
273 HDD_G_MODE_RATETAB(120, 0x40, 0),
274 HDD_G_MODE_RATETAB(180, 0x80, 0),
275 HDD_G_MODE_RATETAB(240, 0x100, 0),
276 HDD_G_MODE_RATETAB(360, 0x200, 0),
277 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530279};
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
281static struct ieee80211_rate a_mode_rates[] =
282{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283 HDD_G_MODE_RATETAB(60, 0x10, 0),
284 HDD_G_MODE_RATETAB(90, 0x20, 0),
285 HDD_G_MODE_RATETAB(120, 0x40, 0),
286 HDD_G_MODE_RATETAB(180, 0x80, 0),
287 HDD_G_MODE_RATETAB(240, 0x100, 0),
288 HDD_G_MODE_RATETAB(360, 0x200, 0),
289 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 HDD_G_MODE_RATETAB(540, 0x800, 0),
291};
292
293static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
294{
295 .channels = hdd_channels_2_4_GHZ,
296 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
297 .band = IEEE80211_BAND_2GHZ,
298 .bitrates = g_mode_rates,
299 .n_bitrates = g_mode_rates_size,
300 .ht_cap.ht_supported = 1,
301 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
302 | IEEE80211_HT_CAP_GRN_FLD
303 | IEEE80211_HT_CAP_DSSSCCK40
304 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
305 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
306 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
307 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
308 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
309 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
310};
311
Jeff Johnson295189b2012-06-20 16:38:30 -0700312static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
313{
314 .channels = hdd_social_channels_2_4_GHZ,
315 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
316 .band = IEEE80211_BAND_2GHZ,
317 .bitrates = g_mode_rates,
318 .n_bitrates = g_mode_rates_size,
319 .ht_cap.ht_supported = 1,
320 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
321 | IEEE80211_HT_CAP_GRN_FLD
322 | IEEE80211_HT_CAP_DSSSCCK40
323 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
324 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
325 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
326 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
327 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
328 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
329};
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
331static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
332{
333 .channels = hdd_channels_5_GHZ,
334 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
335 .band = IEEE80211_BAND_5GHZ,
336 .bitrates = a_mode_rates,
337 .n_bitrates = a_mode_rates_size,
338 .ht_cap.ht_supported = 1,
339 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
340 | IEEE80211_HT_CAP_GRN_FLD
341 | IEEE80211_HT_CAP_DSSSCCK40
342 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
343 | IEEE80211_HT_CAP_SGI_40
344 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
345 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
346 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
347 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
348 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
349 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
350};
351
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530352/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 TX/RX direction for each kind of interface */
354static const struct ieee80211_txrx_stypes
355wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
356 [NL80211_IFTYPE_STATION] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ACTION) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ),
360 },
361 [NL80211_IFTYPE_AP] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
365 BIT(SIR_MAC_MGMT_PROBE_REQ) |
366 BIT(SIR_MAC_MGMT_DISASSOC) |
367 BIT(SIR_MAC_MGMT_AUTH) |
368 BIT(SIR_MAC_MGMT_DEAUTH) |
369 BIT(SIR_MAC_MGMT_ACTION),
370 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700371 [NL80211_IFTYPE_ADHOC] = {
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 [NL80211_IFTYPE_P2P_CLIENT] = {
382 .tx = 0xffff,
383 .rx = BIT(SIR_MAC_MGMT_ACTION) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ),
385 },
386 [NL80211_IFTYPE_P2P_GO] = {
387 /* This is also same as for SoftAP */
388 .tx = 0xffff,
389 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
391 BIT(SIR_MAC_MGMT_PROBE_REQ) |
392 BIT(SIR_MAC_MGMT_DISASSOC) |
393 BIT(SIR_MAC_MGMT_AUTH) |
394 BIT(SIR_MAC_MGMT_DEAUTH) |
395 BIT(SIR_MAC_MGMT_ACTION),
396 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700397};
398
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800400static const struct ieee80211_iface_limit
401wlan_hdd_iface_limit[] = {
402 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800403 /* max = 3 ; Our driver create two interfaces during driver init
404 * wlan0 and p2p0 interfaces. p2p0 is considered as station
405 * interface until a group is formed. In JB architecture, once the
406 * group is formed, interface type of p2p0 is changed to P2P GO or
407 * Client.
408 * When supplicant remove the group, it first issue a set interface
409 * cmd to change the mode back to Station. In JB this works fine as
410 * we advertize two station type interface during driver init.
411 * Some vendors create separate interface for P2P GO/Client,
412 * after group formation(Third one). But while group remove
413 * supplicant first tries to change the mode(3rd interface) to STATION
414 * But as we advertized only two sta type interfaces nl80211 was
415 * returning error for the third one which was leading to failure in
416 * delete interface. Ideally while removing the group, supplicant
417 * should not try to change the 3rd interface mode to Station type.
418 * Till we get a fix in wpa_supplicant, we advertize max STA
419 * interface type to 3
420 */
421 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422 .types = BIT(NL80211_IFTYPE_STATION),
423 },
424 {
425 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700426 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 },
428 {
429 .max = 1,
430 .types = BIT(NL80211_IFTYPE_P2P_GO) |
431 BIT(NL80211_IFTYPE_P2P_CLIENT),
432 },
433};
434
435/* By default, only single channel concurrency is allowed */
436static struct ieee80211_iface_combination
437wlan_hdd_iface_combination = {
438 .limits = wlan_hdd_iface_limit,
439 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800440 /*
441 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
442 * and p2p0 interfaces during driver init
443 * Some vendors create separate interface for P2P operations.
444 * wlan0: STA interface
445 * p2p0: P2P Device interface, action frames goes
446 * through this interface.
447 * p2p-xx: P2P interface, After GO negotiation this interface is
448 * created for p2p operations(GO/CLIENT interface).
449 */
450 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800451 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
452 .beacon_int_infra_match = false,
453};
454#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455
Jeff Johnson295189b2012-06-20 16:38:30 -0700456static struct cfg80211_ops wlan_hdd_cfg80211_ops;
457
458/* Data rate 100KBPS based on IE Index */
459struct index_data_rate_type
460{
461 v_U8_t beacon_rate_index;
462 v_U16_t supported_rate[4];
463};
464
465/* 11B, 11G Rate table include Basic rate and Extended rate
466 The IDX field is the rate index
467 The HI field is the rate when RSSI is strong or being ignored
468 (in this case we report actual rate)
469 The MID field is the rate when RSSI is moderate
470 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
471 The LO field is the rate when RSSI is low
472 (in this case we don't report rates, actual current rate used)
473 */
474static const struct
475{
476 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700478} supported_data_rate[] =
479{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480/* IDX HI HM LM LO (RSSI-based index */
481 {2, { 10, 10, 10, 0}},
482 {4, { 20, 20, 10, 0}},
483 {11, { 55, 20, 10, 0}},
484 {12, { 60, 55, 20, 0}},
485 {18, { 90, 55, 20, 0}},
486 {22, {110, 55, 20, 0}},
487 {24, {120, 90, 60, 0}},
488 {36, {180, 120, 60, 0}},
489 {44, {220, 180, 60, 0}},
490 {48, {240, 180, 90, 0}},
491 {66, {330, 180, 90, 0}},
492 {72, {360, 240, 90, 0}},
493 {96, {480, 240, 120, 0}},
494 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700495};
496
497/* MCS Based rate table */
498static struct index_data_rate_type supported_mcs_rate[] =
499{
500/* MCS L20 L40 S20 S40 */
501 {0, {65, 135, 72, 150}},
502 {1, {130, 270, 144, 300}},
503 {2, {195, 405, 217, 450}},
504 {3, {260, 540, 289, 600}},
505 {4, {390, 810, 433, 900}},
506 {5, {520, 1080, 578, 1200}},
507 {6, {585, 1215, 650, 1350}},
508 {7, {650, 1350, 722, 1500}}
509};
510
Leo Chang6f8870f2013-03-26 18:11:36 -0700511#ifdef WLAN_FEATURE_11AC
512
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530513#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700514
515struct index_vht_data_rate_type
516{
517 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518 v_U16_t supported_VHT80_rate[2];
519 v_U16_t supported_VHT40_rate[2];
520 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700521};
522
523typedef enum
524{
525 DATA_RATE_11AC_MAX_MCS_7,
526 DATA_RATE_11AC_MAX_MCS_8,
527 DATA_RATE_11AC_MAX_MCS_9,
528 DATA_RATE_11AC_MAX_MCS_NA
529} eDataRate11ACMaxMcs;
530
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530531/* SSID broadcast type */
532typedef enum eSSIDBcastType
533{
534 eBCAST_UNKNOWN = 0,
535 eBCAST_NORMAL = 1,
536 eBCAST_HIDDEN = 2,
537} tSSIDBcastType;
538
Leo Chang6f8870f2013-03-26 18:11:36 -0700539/* MCS Based VHT rate table */
540static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
541{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530542/* MCS L80 S80 L40 S40 L20 S40*/
543 {0, {293, 325}, {135, 150}, {65, 72}},
544 {1, {585, 650}, {270, 300}, {130, 144}},
545 {2, {878, 975}, {405, 450}, {195, 217}},
546 {3, {1170, 1300}, {540, 600}, {260, 289}},
547 {4, {1755, 1950}, {810, 900}, {390, 433}},
548 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
549 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
550 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
551 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
552 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700553};
554#endif /* WLAN_FEATURE_11AC */
555
c_hpothu79aab322014-07-14 21:11:01 +0530556/*array index points to MCS and array value points respective rssi*/
557static int rssiMcsTbl[][10] =
558{
559/*MCS 0 1 2 3 4 5 6 7 8 9*/
560 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
561 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
562 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
563};
564
Jeff Johnson295189b2012-06-20 16:38:30 -0700565extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530566#ifdef FEATURE_WLAN_SCAN_PNO
567static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
626 NULL,
627#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Srinivas Dasari030bad32015-02-18 23:23:54 +0530648/*
649 * FUNCTION: __wlan_hdd_cfg80211_nan_request
650 * This is called when wlan driver needs to send vendor specific
651 * nan request event.
652 */
653static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
654 struct wireless_dev *wdev,
655 const void *data, int data_len)
656{
657 tNanRequestReq nan_req;
658 VOS_STATUS status;
659 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530660 struct net_device *dev = wdev->netdev;
661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
662 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
664
665 if (0 == data_len)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("NAN - Invalid Request, length = 0"));
669 return ret_val;
670 }
671
672 if (NULL == data)
673 {
674 hddLog(VOS_TRACE_LEVEL_ERROR,
675 FL("NAN - Invalid Request, data is NULL"));
676 return ret_val;
677 }
678
679 status = wlan_hdd_validate_context(pHddCtx);
680 if (0 != status)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("HDD context is not valid"));
684 return -EINVAL;
685 }
686
687 hddLog(LOG1, FL("Received NAN command"));
688 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
689 (tANI_U8 *)data, data_len);
690
691 /* check the NAN Capability */
692 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
693 {
694 hddLog(VOS_TRACE_LEVEL_ERROR,
695 FL("NAN is not supported by Firmware"));
696 return -EINVAL;
697 }
698
699 nan_req.request_data_len = data_len;
700 nan_req.request_data = data;
701
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530702 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530703 if (VOS_STATUS_SUCCESS == status)
704 {
705 ret_val = 0;
706 }
707 return ret_val;
708}
709
710/*
711 * FUNCTION: wlan_hdd_cfg80211_nan_request
712 * Wrapper to protect the nan vendor command from ssr
713 */
714static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
715 struct wireless_dev *wdev,
716 const void *data, int data_len)
717{
718 int ret;
719
720 vos_ssr_protect(__func__);
721 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
722 vos_ssr_unprotect(__func__);
723
724 return ret;
725}
726
727/*
728 * FUNCTION: wlan_hdd_cfg80211_nan_callback
729 * This is a callback function and it gets called
730 * when we need to report nan response event to
731 * upper layers.
732 */
733static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
734{
735 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
736 struct sk_buff *vendor_event;
737 int status;
738 tSirNanEvent *data;
739
740 ENTER();
741 if (NULL == msg)
742 {
743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
744 FL(" msg received here is null"));
745 return;
746 }
747 data = msg;
748
749 status = wlan_hdd_validate_context(pHddCtx);
750
751 if (0 != status)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("HDD context is not valid"));
755 return;
756 }
757
758 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
760 NULL,
761#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530762 data->event_data_len +
763 NLMSG_HDRLEN,
764 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
765 GFP_KERNEL);
766
767 if (!vendor_event)
768 {
769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
770 FL("cfg80211_vendor_event_alloc failed"));
771 return;
772 }
773 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
774 data->event_data_len, data->event_data))
775 {
776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
777 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
778 kfree_skb(vendor_event);
779 return;
780 }
781 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
782 EXIT();
783}
784
785/*
786 * FUNCTION: wlan_hdd_cfg80211_nan_init
787 * This function is called to register the callback to sme layer
788 */
789inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
790{
791 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
792}
793
794
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795#ifdef WLAN_FEATURE_LINK_LAYER_STATS
796
797static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
798 struct sk_buff *vendor_event)
799{
800 if (nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
802 stats->rate.preamble) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
805 stats->rate.nss) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
808 stats->rate.bw) ||
809 nla_put_u8(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
811 stats->rate.rateMcsIdx) ||
812 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
813 stats->rate.bitrate ) ||
814 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
815 stats->txMpdu ) ||
816 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
817 stats->rxMpdu ) ||
818 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
819 stats->mpduLost ) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
821 stats->retries) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
824 stats->retriesShort ) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
827 stats->retriesLong))
828 {
829 hddLog(VOS_TRACE_LEVEL_ERROR,
830 FL("QCA_WLAN_VENDOR_ATTR put fail"));
831 return FALSE;
832 }
833 return TRUE;
834}
835
836static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
837 struct sk_buff *vendor_event)
838{
839 u32 i = 0;
840 struct nlattr *rateInfo;
841 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
842 stats->type) ||
843 nla_put(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
845 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
848 stats->capabilities) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
851 stats->numRate))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 goto error;
856 }
857
858 rateInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530860 if(!rateInfo)
861 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530862 for (i = 0; i < stats->numRate; i++)
863 {
864 struct nlattr *rates;
865 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
866 stats->rateStats +
867 (i * sizeof(tSirWifiRateStat)));
868 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530869 if(!rates)
870 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530871
872 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
873 {
874 hddLog(VOS_TRACE_LEVEL_ERROR,
875 FL("QCA_WLAN_VENDOR_ATTR put fail"));
876 return FALSE;
877 }
878 nla_nest_end(vendor_event, rates);
879 }
880 nla_nest_end(vendor_event, rateInfo);
881
882 return TRUE;
883error:
884 return FALSE;
885}
886
887static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
888 struct sk_buff *vendor_event)
889{
890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
891 stats->ac ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
894 stats->txMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
897 stats->rxMpdu ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
900 stats->txMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
903 stats->rxMcast ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
906 stats->rxAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
909 stats->txAmpdu ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
912 stats->mpduLost )||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
915 stats->retries ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
918 stats->retriesShort ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
921 stats->retriesLong ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
924 stats->contentionTimeMin ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
927 stats->contentionTimeMax ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
930 stats->contentionTimeAvg ) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
933 stats->contentionNumSamples ))
934 {
935 hddLog(VOS_TRACE_LEVEL_ERROR,
936 FL("QCA_WLAN_VENDOR_ATTR put fail") );
937 return FALSE;
938 }
939 return TRUE;
940}
941
942static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
943 struct sk_buff *vendor_event)
944{
Dino Myclec8f3f332014-07-21 16:48:27 +0530945 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
949 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
952 stats->state ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
955 stats->roaming ) ||
956 nla_put_u32(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
958 stats->capabilities ) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
961 strlen(stats->ssid), stats->ssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
964 WNI_CFG_BSSID_LEN, stats->bssid) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
968 nla_put(vendor_event,
969 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
970 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
971 )
972 {
973 hddLog(VOS_TRACE_LEVEL_ERROR,
974 FL("QCA_WLAN_VENDOR_ATTR put fail") );
975 return FALSE;
976 }
977 return TRUE;
978}
979
Dino Mycle3b9536d2014-07-09 22:05:24 +0530980static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
981 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530982 struct sk_buff *vendor_event)
983{
984 int i = 0;
985 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
987 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530988 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530989
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 if (FALSE == put_wifi_interface_info(
991 &pWifiIfaceStat->info,
992 vendor_event))
993 {
994 hddLog(VOS_TRACE_LEVEL_ERROR,
995 FL("QCA_WLAN_VENDOR_ATTR put fail") );
996 return FALSE;
997
998 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530999 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1000 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1001 if (NULL == pWifiIfaceStatTL)
1002 {
1003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1004 return FALSE;
1005 }
1006
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301007 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1011
1012 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1015 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301016
1017 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1018 {
1019 if (VOS_STATUS_SUCCESS ==
1020 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1021 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1022 {
1023 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1024 * obtained from TL structure
1025 */
1026
1027 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1028 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301029 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039
Srinivas Dasari98947432014-11-07 19:41:24 +05301040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1046 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048
Srinivas Dasari98947432014-11-07 19:41:24 +05301049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1050 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1052 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1054 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1056 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301057 }
1058 else
1059 {
1060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1061 }
1062
Dino Mycle3b9536d2014-07-09 22:05:24 +05301063 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1065 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1069 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1070 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1071 }
1072 else
1073 {
1074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1075 }
1076
1077
Sunil Duttc69bccb2014-05-26 21:30:20 +05301078
1079 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1082 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1084 pWifiIfaceStat->beaconRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1087 pWifiIfaceStat->mgmtRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1090 pWifiIfaceStat->mgmtActionRx) ||
1091 nla_put_u32(vendor_event,
1092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1093 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1096 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1099 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1102 pWifiIfaceStat->rssiAck))
1103 {
1104 hddLog(VOS_TRACE_LEVEL_ERROR,
1105 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301106 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301107 return FALSE;
1108 }
1109
1110 wmmInfo = nla_nest_start(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301112 if(!wmmInfo)
1113 {
1114 vos_mem_free(pWifiIfaceStatTL);
1115 return FALSE;
1116 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301117 for (i = 0; i < WIFI_AC_MAX; i++)
1118 {
1119 struct nlattr *wmmStats;
1120 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301121 if(!wmmStats)
1122 {
1123 vos_mem_free(pWifiIfaceStatTL);
1124 return FALSE;
1125 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301126 if (FALSE == put_wifi_wmm_ac_stat(
1127 &pWifiIfaceStat->AccessclassStats[i],
1128 vendor_event))
1129 {
1130 hddLog(VOS_TRACE_LEVEL_ERROR,
1131 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301132 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301133 return FALSE;
1134 }
1135
1136 nla_nest_end(vendor_event, wmmStats);
1137 }
1138 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301139 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301140 return TRUE;
1141}
1142
1143static tSirWifiInterfaceMode
1144 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1145{
1146 switch (deviceMode)
1147 {
1148 case WLAN_HDD_INFRA_STATION:
1149 return WIFI_INTERFACE_STA;
1150 case WLAN_HDD_SOFTAP:
1151 return WIFI_INTERFACE_SOFTAP;
1152 case WLAN_HDD_P2P_CLIENT:
1153 return WIFI_INTERFACE_P2P_CLIENT;
1154 case WLAN_HDD_P2P_GO:
1155 return WIFI_INTERFACE_P2P_GO;
1156 case WLAN_HDD_IBSS:
1157 return WIFI_INTERFACE_IBSS;
1158 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301159 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 }
1161}
1162
1163static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1164 tpSirWifiInterfaceInfo pInfo)
1165{
1166 v_U8_t *staMac = NULL;
1167 hdd_station_ctx_t *pHddStaCtx;
1168 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1169 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1170
1171 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1172
1173 vos_mem_copy(pInfo->macAddr,
1174 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1175
1176 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1178 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1179 {
1180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1181 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1182 {
1183 pInfo->state = WIFI_DISCONNECTED;
1184 }
1185 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1186 {
1187 hddLog(VOS_TRACE_LEVEL_ERROR,
1188 "%s: Session ID %d, Connection is in progress", __func__,
1189 pAdapter->sessionId);
1190 pInfo->state = WIFI_ASSOCIATING;
1191 }
1192 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1193 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1194 {
1195 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: client " MAC_ADDRESS_STR
1198 " is in the middle of WPS/EAPOL exchange.", __func__,
1199 MAC_ADDR_ARRAY(staMac));
1200 pInfo->state = WIFI_AUTHENTICATING;
1201 }
1202 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1203 {
1204 pInfo->state = WIFI_ASSOCIATED;
1205 vos_mem_copy(pInfo->bssid,
1206 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1207 vos_mem_copy(pInfo->ssid,
1208 pHddStaCtx->conn_info.SSID.SSID.ssId,
1209 pHddStaCtx->conn_info.SSID.SSID.length);
1210 //NULL Terminate the string.
1211 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1212 }
1213 }
1214 vos_mem_copy(pInfo->countryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 vos_mem_copy(pInfo->apCountryStr,
1218 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1219
1220 return TRUE;
1221}
1222
1223/*
1224 * hdd_link_layer_process_peer_stats () - This function is called after
1225 * receiving Link Layer Peer statistics from FW.This function converts
1226 * the firmware data to the NL data and sends the same to the kernel/upper
1227 * layers.
1228 */
1229static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1230 v_VOID_t *pData)
1231{
1232 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301233 tpSirWifiPeerStat pWifiPeerStat;
1234 tpSirWifiPeerInfo pWifiPeerInfo;
1235 struct nlattr *peerInfo;
1236 struct sk_buff *vendor_event;
1237 int status, i;
1238
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301239 ENTER();
1240
Sunil Duttc69bccb2014-05-26 21:30:20 +05301241 status = wlan_hdd_validate_context(pHddCtx);
1242 if (0 != status)
1243 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301244 return;
1245 }
1246
1247 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1248
1249 hddLog(VOS_TRACE_LEVEL_INFO,
1250 "LL_STATS_PEER_ALL : numPeers %u",
1251 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301252 /*
1253 * Allocate a size of 4096 for the peer stats comprising
1254 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1255 * sizeof (tSirWifiRateStat).Each field is put with an
1256 * NL attribute.The size of 4096 is considered assuming
1257 * that number of rates shall not exceed beyond 50 with
1258 * the sizeof (tSirWifiRateStat) being 32.
1259 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301260 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1261 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 if (!vendor_event)
1263 {
1264 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301265 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 __func__);
1267 return;
1268 }
1269 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1271 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1272 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1274 pWifiPeerStat->numPeers))
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1278 kfree_skb(vendor_event);
1279 return;
1280 }
1281
1282 peerInfo = nla_nest_start(vendor_event,
1283 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301284 if(!peerInfo)
1285 {
1286 hddLog(VOS_TRACE_LEVEL_ERROR,
1287 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1288 __func__);
1289 kfree_skb(vendor_event);
1290 return;
1291 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301292
1293 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1294 pWifiPeerStat->peerInfo);
1295
1296 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1297 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301299 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301301 if(!peers)
1302 {
1303 hddLog(VOS_TRACE_LEVEL_ERROR,
1304 "%s: peer stats put fail",
1305 __func__);
1306 kfree_skb(vendor_event);
1307 return;
1308 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301309 if (FALSE == put_wifi_peer_info(
1310 pWifiPeerInfo, vendor_event))
1311 {
1312 hddLog(VOS_TRACE_LEVEL_ERROR,
1313 "%s: put_wifi_peer_info put fail", __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
1317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo +
1320 (i * sizeof(tSirWifiPeerInfo)) +
1321 (numRate * sizeof (tSirWifiRateStat)));
1322 nla_nest_end(vendor_event, peers);
1323 }
1324 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301325 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301326 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301327}
1328
1329/*
1330 * hdd_link_layer_process_iface_stats () - This function is called after
1331 * receiving Link Layer Interface statistics from FW.This function converts
1332 * the firmware data to the NL data and sends the same to the kernel/upper
1333 * layers.
1334 */
1335static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1336 v_VOID_t *pData)
1337{
1338 tpSirWifiIfaceStat pWifiIfaceStat;
1339 struct sk_buff *vendor_event;
1340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1341 int status;
1342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301343 ENTER();
1344
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 status = wlan_hdd_validate_context(pHddCtx);
1346 if (0 != status)
1347 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301348 return;
1349 }
1350 /*
1351 * Allocate a size of 4096 for the interface stats comprising
1352 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1353 * assuming that all these fit with in the limit.Please take
1354 * a call on the limit based on the data requirements on
1355 * interface statistics.
1356 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301357 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1358 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 if (!vendor_event)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301362 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 return;
1364 }
1365
1366 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1367
Dino Mycle3b9536d2014-07-09 22:05:24 +05301368
1369 if (FALSE == hdd_get_interface_info( pAdapter,
1370 &pWifiIfaceStat->info))
1371 {
1372 hddLog(VOS_TRACE_LEVEL_ERROR,
1373 FL("hdd_get_interface_info get fail") );
1374 kfree_skb(vendor_event);
1375 return;
1376 }
1377
1378 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1379 vendor_event))
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
1382 FL("put_wifi_iface_stats fail") );
1383 kfree_skb(vendor_event);
1384 return;
1385 }
1386
Sunil Duttc69bccb2014-05-26 21:30:20 +05301387 hddLog(VOS_TRACE_LEVEL_INFO,
1388 "WMI_LINK_STATS_IFACE Data");
1389
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301390 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301447 if (!vendor_event)
1448 {
1449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301451 return;
1452 }
1453
1454 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1457 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
Sunil Duttc69bccb2014-05-26 21:30:20 +05301515 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301516 if(!chInfo)
1517 {
1518 hddLog(VOS_TRACE_LEVEL_ERROR,
1519 "%s: failed to put chInfo",
1520 __func__);
1521 kfree_skb(vendor_event);
1522 return;
1523 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524
1525 if (nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1527 pWifiChannelStats->channel.width) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1530 pWifiChannelStats->channel.centerFreq) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1533 pWifiChannelStats->channel.centerFreq0) ||
1534 nla_put_u32(vendor_event,
1535 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1536 pWifiChannelStats->channel.centerFreq1) ||
1537 nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1539 pWifiChannelStats->onTime) ||
1540 nla_put_u32(vendor_event,
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1542 pWifiChannelStats->ccaBusyTime))
1543 {
1544 hddLog(VOS_TRACE_LEVEL_ERROR,
1545 FL("cfg80211_vendor_event_alloc failed") );
1546 kfree_skb(vendor_event);
1547 return ;
1548 }
1549 nla_nest_end(vendor_event, chInfo);
1550 }
1551 nla_nest_end(vendor_event, chList);
1552
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301553 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301554
1555 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 return;
1557}
1558
1559/*
1560 * hdd_link_layer_stats_ind_callback () - This function is called after
1561 * receiving Link Layer indications from FW.This callback converts the firmware
1562 * data to the NL data and send the same to the kernel/upper layers.
1563 */
1564static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1565 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301566 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567{
Dino Mycled3d50022014-07-07 12:58:25 +05301568 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1569 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301570 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301571 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 int status;
1573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301576 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301577 if (0 != status)
1578 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 return;
1580 }
1581
Dino Mycled3d50022014-07-07 12:58:25 +05301582 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1583 if (NULL == pAdapter)
1584 {
1585 hddLog(VOS_TRACE_LEVEL_ERROR,
1586 FL(" MAC address %pM does not exist with host"),
1587 macAddr);
1588 return;
1589 }
1590
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "%s: Interface: %s LLStats indType: %d", __func__,
1593 pAdapter->dev->name, indType);
1594
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 switch (indType)
1596 {
1597 case SIR_HAL_LL_STATS_RESULTS_RSP:
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301600 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1601 "respId = %u, moreResultToFollow = %u",
1602 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1603 macAddr, linkLayerStatsResults->respId,
1604 linkLayerStatsResults->moreResultToFollow);
1605
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301606 spin_lock(&hdd_context_lock);
1607 context = &pHddCtx->ll_stats_context;
1608 /* validate response received from target */
1609 if ((context->request_id != linkLayerStatsResults->respId) ||
1610 !(context->request_bitmap & linkLayerStatsResults->paramId))
1611 {
1612 spin_unlock(&hdd_context_lock);
1613 hddLog(LOGE,
1614 FL("Error : Request id %d response id %d request bitmap 0x%x"
1615 "response bitmap 0x%x"),
1616 context->request_id, linkLayerStatsResults->respId,
1617 context->request_bitmap, linkLayerStatsResults->paramId);
1618 return;
1619 }
1620 spin_unlock(&hdd_context_lock);
1621
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1623 {
1624 hdd_link_layer_process_radio_stats(pAdapter,
1625 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1628 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 }
1630 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1631 {
1632 hdd_link_layer_process_iface_stats(pAdapter,
1633 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301634 spin_lock(&hdd_context_lock);
1635 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1636 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 }
1638 else if ( linkLayerStatsResults->paramId &
1639 WMI_LINK_STATS_ALL_PEER )
1640 {
1641 hdd_link_layer_process_peer_stats(pAdapter,
1642 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301643 spin_lock(&hdd_context_lock);
1644 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1645 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646 } /* WMI_LINK_STATS_ALL_PEER */
1647 else
1648 {
1649 hddLog(VOS_TRACE_LEVEL_ERROR,
1650 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1651 }
1652
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301653 spin_lock(&hdd_context_lock);
1654 /* complete response event if all requests are completed */
1655 if (0 == context->request_bitmap)
1656 complete(&context->response_event);
1657 spin_unlock(&hdd_context_lock);
1658
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 break;
1660 }
1661 default:
1662 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1663 break;
1664 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301665
1666 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 return;
1668}
1669
1670const struct
1671nla_policy
1672qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1673{
1674 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1675 { .type = NLA_U32 },
1676 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1677 { .type = NLA_U32 },
1678};
1679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301680static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1681 struct wireless_dev *wdev,
1682 const void *data,
1683 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684{
1685 int status;
1686 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 struct net_device *dev = wdev->netdev;
1689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301692 ENTER();
1693
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 status = wlan_hdd_validate_context(pHddCtx);
1695 if (0 != status)
1696 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return -EINVAL;
1698 }
1699
1700 if (NULL == pAdapter)
1701 {
1702 hddLog(VOS_TRACE_LEVEL_ERROR,
1703 FL("HDD adapter is Null"));
1704 return -ENODEV;
1705 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 /* check the LLStats Capability */
1707 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1708 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("Link Layer Statistics not supported by Firmware"));
1712 return -EINVAL;
1713 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714
1715 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1716 (struct nlattr *)data,
1717 data_len, qca_wlan_vendor_ll_set_policy))
1718 {
1719 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1720 return -EINVAL;
1721 }
1722 if (!tb_vendor
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1726 return -EINVAL;
1727 }
1728 if (!tb_vendor[
1729 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301735 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1740
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301742 nla_get_u32(
1743 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1744
Dino Mycled3d50022014-07-07 12:58:25 +05301745 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1746 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747
1748
1749 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301750 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1751 "Statistics Gathering = %d ",
1752 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1753 linkLayerStatsSetReq.mpduSizeThreshold,
1754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1770 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301771 return -EINVAL;
1772 }
1773
1774 pAdapter->isLinkLayerStatsSet = 1;
1775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301776 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777 return 0;
1778}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301779static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1780 struct wireless_dev *wdev,
1781 const void *data,
1782 int data_len)
1783{
1784 int ret = 0;
1785
1786 vos_ssr_protect(__func__);
1787 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1788 vos_ssr_unprotect(__func__);
1789
1790 return ret;
1791}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792
1793const struct
1794nla_policy
1795qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1796{
1797 /* Unsigned 32bit value provided by the caller issuing the GET stats
1798 * command. When reporting
1799 * the stats results, the driver uses the same value to indicate
1800 * which GET request the results
1801 * correspond to.
1802 */
1803 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1804
1805 /* Unsigned 32bit value . bit mask to identify what statistics are
1806 requested for retrieval */
1807 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1808};
1809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301810static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1811 struct wireless_dev *wdev,
1812 const void *data,
1813 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301815 unsigned long rc;
1816 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1818 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 struct net_device *dev = wdev->netdev;
1821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301822 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 int status;
1824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301825 ENTER();
1826
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827 status = wlan_hdd_validate_context(pHddCtx);
1828 if (0 != status)
1829 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 return -EINVAL ;
1831 }
1832
1833 if (NULL == pAdapter)
1834 {
1835 hddLog(VOS_TRACE_LEVEL_FATAL,
1836 "%s: HDD adapter is Null", __func__);
1837 return -ENODEV;
1838 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301839
1840 if (pHddStaCtx == NULL)
1841 {
1842 hddLog(VOS_TRACE_LEVEL_FATAL,
1843 "%s: HddStaCtx is Null", __func__);
1844 return -ENODEV;
1845 }
1846
Dino Mycledf0a5d92014-07-04 09:41:55 +05301847 /* check the LLStats Capability */
1848 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1849 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1850 {
1851 hddLog(VOS_TRACE_LEVEL_ERROR,
1852 FL("Link Layer Statistics not supported by Firmware"));
1853 return -EINVAL;
1854 }
1855
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856
1857 if (!pAdapter->isLinkLayerStatsSet)
1858 {
1859 hddLog(VOS_TRACE_LEVEL_FATAL,
1860 "%s: isLinkLayerStatsSet : %d",
1861 __func__, pAdapter->isLinkLayerStatsSet);
1862 return -EINVAL;
1863 }
1864
Mukul Sharma10313ba2015-07-29 19:14:39 +05301865 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "%s: Roaming in progress, so unable to proceed this request", __func__);
1869 return -EBUSY;
1870 }
1871
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1873 (struct nlattr *)data,
1874 data_len, qca_wlan_vendor_ll_get_policy))
1875 {
1876 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1877 return -EINVAL;
1878 }
1879
1880 if (!tb_vendor
1881 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1882 {
1883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1884 return -EINVAL;
1885 }
1886
1887 if (!tb_vendor
1888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1889 {
1890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1891 return -EINVAL;
1892 }
1893
Sunil Duttc69bccb2014-05-26 21:30:20 +05301894
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 nla_get_u32( tb_vendor[
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1901
Dino Mycled3d50022014-07-07 12:58:25 +05301902 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1903 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904
1905 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301906 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1907 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301910 spin_lock(&hdd_context_lock);
1911 context = &pHddCtx->ll_stats_context;
1912 context->request_id = linkLayerStatsGetReq.reqId;
1913 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1914 INIT_COMPLETION(context->response_event);
1915 spin_unlock(&hdd_context_lock);
1916
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1921 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 return -EINVAL;
1923 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301924
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301925 rc = wait_for_completion_timeout(&context->response_event,
1926 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1927 if (!rc)
1928 {
1929 hddLog(LOGE,
1930 FL("Target response timed out request id %d request bitmap 0x%x"),
1931 context->request_id, context->request_bitmap);
1932 return -ETIMEDOUT;
1933 }
1934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301935 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 return 0;
1937}
1938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301939static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1940 struct wireless_dev *wdev,
1941 const void *data,
1942 int data_len)
1943{
1944 int ret = 0;
1945
1946 vos_ssr_protect(__func__);
1947 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1948 vos_ssr_unprotect(__func__);
1949
1950 return ret;
1951}
1952
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953const struct
1954nla_policy
1955qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1956{
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1960 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1961};
1962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301963static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1964 struct wireless_dev *wdev,
1965 const void *data,
1966 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301967{
1968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1969 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301970 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971 struct net_device *dev = wdev->netdev;
1972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1973 u32 statsClearReqMask;
1974 u8 stopReq;
1975 int status;
1976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301977 ENTER();
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979 status = wlan_hdd_validate_context(pHddCtx);
1980 if (0 != status)
1981 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982 return -EINVAL;
1983 }
1984
1985 if (NULL == pAdapter)
1986 {
1987 hddLog(VOS_TRACE_LEVEL_FATAL,
1988 "%s: HDD adapter is Null", __func__);
1989 return -ENODEV;
1990 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301991 /* check the LLStats Capability */
1992 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1993 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("Enable LLStats Capability"));
1997 return -EINVAL;
1998 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999
2000 if (!pAdapter->isLinkLayerStatsSet)
2001 {
2002 hddLog(VOS_TRACE_LEVEL_FATAL,
2003 "%s: isLinkLayerStatsSet : %d",
2004 __func__, pAdapter->isLinkLayerStatsSet);
2005 return -EINVAL;
2006 }
2007
2008 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2009 (struct nlattr *)data,
2010 data_len, qca_wlan_vendor_ll_clr_policy))
2011 {
2012 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2013 return -EINVAL;
2014 }
2015
2016 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2017
2018 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2019 {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2021 return -EINVAL;
2022
2023 }
2024
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
Dino Mycledf0a5d92014-07-04 09:41:55 +05302026 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 nla_get_u32(
2028 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2029
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 nla_get_u8(
2032 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2033
2034 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
Dino Mycled3d50022014-07-07 12:58:25 +05302037 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2038 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039
2040 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302041 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2042 "statsClearReqMask = 0x%X, stopReq = %d",
2043 linkLayerStatsClearReq.reqId,
2044 linkLayerStatsClearReq.macAddr,
2045 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047
2048 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302049 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050 {
2051 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302052 hdd_station_ctx_t *pHddStaCtx;
2053
2054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2055 if (VOS_STATUS_SUCCESS !=
2056 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2057 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2060 "WLANTL_ClearInterfaceStats Failed", __func__);
2061 return -EINVAL;
2062 }
2063 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2064 (statsClearReqMask & WIFI_STATS_IFACE)) {
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2069 }
2070
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2072 2 * sizeof(u32) +
2073 NLMSG_HDRLEN);
2074
2075 if (temp_skbuff != NULL)
2076 {
2077
2078 if (nla_put_u32(temp_skbuff,
2079 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2080 statsClearReqMask) ||
2081 nla_put_u32(temp_skbuff,
2082 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2083 stopReq))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2086 kfree_skb(temp_skbuff);
2087 return -EINVAL;
2088 }
2089 /* If the ask is to stop the stats collection as part of clear
2090 * (stopReq = 1) , ensure that no further requests of get
2091 * go to the firmware by having isLinkLayerStatsSet set to 0.
2092 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 * case the firmware is just asked to clear the statistics.
2095 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302096 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 pAdapter->isLinkLayerStatsSet = 0;
2098 return cfg80211_vendor_cmd_reply(temp_skbuff);
2099 }
2100 return -ENOMEM;
2101 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302102
2103 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 return -EINVAL;
2105}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302106static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2107 struct wireless_dev *wdev,
2108 const void *data,
2109 int data_len)
2110{
2111 int ret = 0;
2112
2113 vos_ssr_protect(__func__);
2114 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2115 vos_ssr_unprotect(__func__);
2116
2117 return ret;
2118
2119
2120}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302121#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2122
Dino Mycle6fb96c12014-06-10 11:52:40 +05302123#ifdef WLAN_FEATURE_EXTSCAN
2124static const struct nla_policy
2125wlan_hdd_extscan_config_policy
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2127{
2128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2129 { .type = NLA_U32 },
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2131 { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2137
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2142 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2144 { .type = NLA_U32 },
2145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2146 { .type = NLA_U32 },
2147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2148 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2150 { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2154 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2156 { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302158 { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2160 { .type = NLA_U8 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2162 { .type = NLA_U8 },
2163
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2167 { .type = NLA_UNSPEC },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2169 { .type = NLA_S32 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2171 { .type = NLA_S32 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2175 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2177 { .type = NLA_U32 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2179 { .type = NLA_BINARY,
2180 .len = IEEE80211_MAX_SSID_LEN + 1 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302182 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2184 { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2188 { .type = NLA_S32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2190 { .type = NLA_S32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193};
2194
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302195/**
2196 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2197 * @ctx: hdd global context
2198 * @data: capabilities data
2199 *
2200 * Return: none
2201 */
2202static void
2203wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302204{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302205 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302206 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302207 tSirEXTScanCapabilitiesEvent *data =
2208 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302210 ENTER();
2211
2212 if (wlan_hdd_validate_context(pHddCtx))
2213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302214 return;
2215 }
2216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302217 if (!pMsg)
2218 {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2220 return;
2221 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302222
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302223 vos_spin_lock_acquire(&hdd_context_lock);
2224
2225 context = &pHddCtx->ext_scan_context;
2226 /* validate response received from target*/
2227 if (context->request_id != data->requestId)
2228 {
2229 vos_spin_lock_release(&hdd_context_lock);
2230 hddLog(LOGE,
2231 FL("Target response id did not match: request_id %d resposne_id %d"),
2232 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302233 return;
2234 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 else
2236 {
2237 context->capability_response = *data;
2238 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239 }
2240
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Dino Mycle6fb96c12014-06-10 11:52:40 +05302243 return;
2244}
2245
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302246/*
2247 * define short names for the global vendor params
2248 * used by wlan_hdd_send_ext_scan_capability()
2249 */
2250#define PARAM_REQUEST_ID \
2251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2252#define PARAM_STATUS \
2253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2254#define MAX_SCAN_CACHE_SIZE \
2255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2256#define MAX_SCAN_BUCKETS \
2257 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2258#define MAX_AP_CACHE_PER_SCAN \
2259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2260#define MAX_RSSI_SAMPLE_SIZE \
2261 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2262#define MAX_SCAN_RPT_THRHOLD \
2263 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2264#define MAX_HOTLIST_BSSIDS \
2265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2266#define MAX_BSSID_HISTORY_ENTRIES \
2267 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2268#define MAX_HOTLIST_SSIDS \
2269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302270#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272
2273static int wlan_hdd_send_ext_scan_capability(void *ctx)
2274{
2275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2276 struct sk_buff *skb = NULL;
2277 int ret;
2278 tSirEXTScanCapabilitiesEvent *data;
2279 tANI_U32 nl_buf_len;
2280
2281 ret = wlan_hdd_validate_context(pHddCtx);
2282 if (0 != ret)
2283 {
2284 return ret;
2285 }
2286
2287 data = &(pHddCtx->ext_scan_context.capability_response);
2288
2289 nl_buf_len = NLMSG_HDRLEN;
2290 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2291 (sizeof(data->status) + NLA_HDRLEN) +
2292 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2293 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2294 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2295 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2296 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2297 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2298 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2299 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2300
2301 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2302
2303 if (!skb)
2304 {
2305 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2306 return -ENOMEM;
2307 }
2308
2309 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2310 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2311 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2312 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2313 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2314 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2315 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2316 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2317
2318 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2319 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2320 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2321 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2322 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2323 data->maxApPerScan) ||
2324 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2325 data->maxRssiSampleSize) ||
2326 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2327 data->maxScanReportingThreshold) ||
2328 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2329 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2330 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302331 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2332 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302333 {
2334 hddLog(LOGE, FL("nla put fail"));
2335 goto nla_put_failure;
2336 }
2337
2338 cfg80211_vendor_cmd_reply(skb);
2339 return 0;
2340
2341nla_put_failure:
2342 kfree_skb(skb);
2343 return -EINVAL;;
2344}
2345
2346/*
2347 * done with short names for the global vendor params
2348 * used by wlan_hdd_send_ext_scan_capability()
2349 */
2350#undef PARAM_REQUEST_ID
2351#undef PARAM_STATUS
2352#undef MAX_SCAN_CACHE_SIZE
2353#undef MAX_SCAN_BUCKETS
2354#undef MAX_AP_CACHE_PER_SCAN
2355#undef MAX_RSSI_SAMPLE_SIZE
2356#undef MAX_SCAN_RPT_THRHOLD
2357#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302358#undef MAX_BSSID_HISTORY_ENTRIES
2359#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302360
2361static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2362{
2363 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2364 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302365 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302366 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302368 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302369
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302370 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302371 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302373 if (!pMsg)
2374 {
2375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 return;
2377 }
2378
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2380 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2381
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302382 context = &pHddCtx->ext_scan_context;
2383 spin_lock(&hdd_context_lock);
2384 if (context->request_id == pData->requestId) {
2385 context->response_status = pData->status ? -EINVAL : 0;
2386 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302388 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
2390 /*
2391 * Store the Request ID for comparing with the requestID obtained
2392 * in other requests.HDD shall return a failure is the extscan_stop
2393 * request is issued with a different requestId as that of the
2394 * extscan_start request. Also, This requestId shall be used while
2395 * indicating the full scan results to the upper layers.
2396 * The requestId is stored with the assumption that the firmware
2397 * shall return the ext scan start request's requestId in ext scan
2398 * start response.
2399 */
2400 if (pData->status == 0)
2401 pMac->sme.extScanStartReqId = pData->requestId;
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405}
2406
2407
2408static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2409{
2410 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302412 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 ENTER();
2415
2416 if (wlan_hdd_validate_context(pHddCtx)){
2417 return;
2418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302420 if (!pMsg)
2421 {
2422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 return;
2424 }
2425
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302426 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2427 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302429 context = &pHddCtx->ext_scan_context;
2430 spin_lock(&hdd_context_lock);
2431 if (context->request_id == pData->requestId) {
2432 context->response_status = pData->status ? -EINVAL : 0;
2433 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302435 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302439}
2440
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2442 void *pMsg)
2443{
2444 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445 tpSirEXTScanSetBssidHotListRspParams pData =
2446 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302447 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302449 ENTER();
2450
2451 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 return;
2453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302455 if (!pMsg)
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2458 return;
2459 }
2460
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302461 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2462 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302463
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302464 context = &pHddCtx->ext_scan_context;
2465 spin_lock(&hdd_context_lock);
2466 if (context->request_id == pData->requestId) {
2467 context->response_status = pData->status ? -EINVAL : 0;
2468 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302470 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302472 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474}
2475
2476static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2477 void *pMsg)
2478{
2479 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480 tpSirEXTScanResetBssidHotlistRspParams pData =
2481 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302482 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302484 ENTER();
2485
2486 if (wlan_hdd_validate_context(pHddCtx)) {
2487 return;
2488 }
2489 if (!pMsg)
2490 {
2491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492 return;
2493 }
2494
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302495 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2496 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302497
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302498 context = &pHddCtx->ext_scan_context;
2499 spin_lock(&hdd_context_lock);
2500 if (context->request_id == pData->requestId) {
2501 context->response_status = pData->status ? -EINVAL : 0;
2502 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302504 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302506 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302508}
2509
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302510static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2511 void *pMsg)
2512{
2513 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2514 tpSirEXTScanSetSsidHotListRspParams pData =
2515 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2516 struct hdd_ext_scan_context *context;
2517
2518 if (wlan_hdd_validate_context(pHddCtx)){
2519 return;
2520 }
2521
2522 if (!pMsg)
2523 {
2524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2525 return;
2526 }
2527
2528 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2529 pData->status);
2530
2531 context = &pHddCtx->ext_scan_context;
2532 spin_lock(&hdd_context_lock);
2533 if (context->request_id == pData->requestId) {
2534 context->response_status = pData->status ? -EINVAL : 0;
2535 complete(&context->response_event);
2536 }
2537 spin_unlock(&hdd_context_lock);
2538
2539 return;
2540}
2541
2542static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2543 void *pMsg)
2544{
2545 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2546 tpSirEXTScanResetSsidHotlistRspParams pData =
2547 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2548 struct hdd_ext_scan_context *context;
2549
2550 if (wlan_hdd_validate_context(pHddCtx)) {
2551 return;
2552 }
2553 if (!pMsg)
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2556 return;
2557 }
2558
2559 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2560 pData->status);
2561
2562 context = &pHddCtx->ext_scan_context;
2563 spin_lock(&hdd_context_lock);
2564 if (context->request_id == pData->requestId) {
2565 context->response_status = pData->status ? -EINVAL : 0;
2566 complete(&context->response_event);
2567 }
2568 spin_unlock(&hdd_context_lock);
2569
2570 return;
2571}
2572
2573
Dino Mycle6fb96c12014-06-10 11:52:40 +05302574static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2575 void *pMsg)
2576{
2577 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2578 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302580 tANI_S32 totalResults;
2581 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2583 struct hdd_ext_scan_context *context;
2584 bool ignore_cached_results = false;
2585 tExtscanCachedScanResult *result;
2586 struct nlattr *nla_results;
2587 tANI_U16 ieLength= 0;
2588 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 ENTER();
2591
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302592 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302593 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302595 if (!pMsg)
2596 {
2597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2598 return;
2599 }
2600
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302601 spin_lock(&hdd_context_lock);
2602 context = &pHddCtx->ext_scan_context;
2603 ignore_cached_results = context->ignore_cached_results;
2604 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302605
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302606 if (ignore_cached_results) {
2607 hddLog(LOGE,
2608 FL("Ignore the cached results received after timeout"));
2609 return;
2610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2613 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302617 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2618 scan_id_index++) {
2619 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 totalResults = result->num_results;
2622 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2623 result->scan_id, result->flags, totalResults);
2624 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 do{
2627 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2628 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2629 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2632 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2633
2634 if (!skb) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed"));
2637 return;
2638 }
2639
2640 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2641
2642 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2643 pData->requestId) ||
2644 nla_put_u32(skb,
2645 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2646 resultsPerEvent)) {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2648 goto fail;
2649 }
2650 if (nla_put_u8(skb,
2651 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2652 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302653 {
2654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2655 goto fail;
2656 }
2657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302658 if (nla_put_u32(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2660 result->scan_id)) {
2661 hddLog(LOGE, FL("put fail"));
2662 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 nla_results = nla_nest_start(skb,
2666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2667 if (!nla_results)
2668 goto fail;
2669
2670 if (resultsPerEvent) {
2671 struct nlattr *aps;
2672 struct nlattr *nla_result;
2673
2674 nla_result = nla_nest_start(skb, scan_id_index);
2675 if(!nla_result)
2676 goto fail;
2677
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id) ||
2681 nla_put_u32(skb,
2682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2683 result->flags) ||
2684 nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2686 totalResults)) {
2687 hddLog(LOGE, FL("put fail"));
2688 goto fail;
2689 }
2690
2691 aps = nla_nest_start(skb,
2692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2693 if (!aps)
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2696 goto fail;
2697 }
2698
2699 head_ptr = (tpSirWifiScanResult) &(result->ap);
2700
2701 for (j = 0; j < resultsPerEvent; j++, i++) {
2702 struct nlattr *ap;
2703 pSirWifiScanResult = head_ptr + i;
2704
2705 /*
2706 * Firmware returns timestamp from WiFi turn ON till
2707 * BSSID was cached (in seconds). Add this with
2708 * time gap between system boot up to WiFi turn ON
2709 * to derive the time since boot when the
2710 * BSSID was cached.
2711 */
2712 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2713 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2714 "Ssid (%s)"
2715 "Bssid: %pM "
2716 "Channel (%u)"
2717 "Rssi (%d)"
2718 "RTT (%u)"
2719 "RTT_SD (%u)"
2720 "Beacon Period %u"
2721 "Capability 0x%x "
2722 "Ie length %d",
2723 i,
2724 pSirWifiScanResult->ts,
2725 pSirWifiScanResult->ssid,
2726 pSirWifiScanResult->bssid,
2727 pSirWifiScanResult->channel,
2728 pSirWifiScanResult->rssi,
2729 pSirWifiScanResult->rtt,
2730 pSirWifiScanResult->rtt_sd,
2731 pSirWifiScanResult->beaconPeriod,
2732 pSirWifiScanResult->capability,
2733 ieLength);
2734
2735 ap = nla_nest_start(skb, j + 1);
2736 if (!ap)
2737 {
2738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2739 goto fail;
2740 }
2741
2742 if (nla_put_u64(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2744 pSirWifiScanResult->ts) )
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749 if (nla_put(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2751 sizeof(pSirWifiScanResult->ssid),
2752 pSirWifiScanResult->ssid) )
2753 {
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2755 goto fail;
2756 }
2757 if (nla_put(skb,
2758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2759 sizeof(pSirWifiScanResult->bssid),
2760 pSirWifiScanResult->bssid) )
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2763 goto fail;
2764 }
2765 if (nla_put_u32(skb,
2766 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2767 pSirWifiScanResult->channel) )
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772 if (nla_put_s32(skb,
2773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2774 pSirWifiScanResult->rssi) )
2775 {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2777 goto fail;
2778 }
2779 if (nla_put_u32(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2781 pSirWifiScanResult->rtt) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2788 pSirWifiScanResult->rtt_sd))
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_u32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2795 pSirWifiScanResult->beaconPeriod))
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2802 pSirWifiScanResult->capability))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2809 ieLength))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814
2815 if (ieLength)
2816 if (nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2818 ieLength, ie)) {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822
2823 nla_nest_end(skb, ap);
2824 }
2825 nla_nest_end(skb, aps);
2826 nla_nest_end(skb, nla_result);
2827 }
2828
2829 nla_nest_end(skb, nla_results);
2830
2831 cfg80211_vendor_cmd_reply(skb);
2832
2833 } while (totalResults > 0);
2834 }
2835
2836 if (!pData->moreData) {
2837 spin_lock(&hdd_context_lock);
2838 context->response_status = 0;
2839 complete(&context->response_event);
2840 spin_unlock(&hdd_context_lock);
2841 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302843 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 return;
2845fail:
2846 kfree_skb(skb);
2847 return;
2848}
2849
2850static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2851 void *pMsg)
2852{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302853 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302854 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2855 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302856 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302858 ENTER();
2859
2860 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302861 hddLog(LOGE,
2862 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 return;
2864 }
2865 if (!pMsg)
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302868 return;
2869 }
2870
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 if (pData->bss_found)
2872 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2873 else
2874 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2875
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2878 NULL,
2879#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302882
2883 if (!skb) {
2884 hddLog(VOS_TRACE_LEVEL_ERROR,
2885 FL("cfg80211_vendor_event_alloc failed"));
2886 return;
2887 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2892 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2893
2894 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302895 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2896 "Ssid (%s) "
2897 "Bssid (" MAC_ADDRESS_STR ") "
2898 "Channel (%u) "
2899 "Rssi (%d) "
2900 "RTT (%u) "
2901 "RTT_SD (%u) ",
2902 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 pData->bssHotlist[i].ts,
2904 pData->bssHotlist[i].ssid,
2905 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2906 pData->bssHotlist[i].channel,
2907 pData->bssHotlist[i].rssi,
2908 pData->bssHotlist[i].rtt,
2909 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 }
2911
2912 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2913 pData->requestId) ||
2914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2918 goto fail;
2919 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 struct nlattr *aps;
2922
2923 aps = nla_nest_start(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2925 if (!aps)
2926 goto fail;
2927
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302928 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 struct nlattr *ap;
2930
2931 ap = nla_nest_start(skb, i + 1);
2932 if (!ap)
2933 goto fail;
2934
2935 if (nla_put_u64(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 nla_put(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 sizeof(pData->bssHotlist[i].ssid),
2941 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 nla_put(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302944 sizeof(pData->bssHotlist[i].bssid),
2945 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 nla_put_u32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 nla_put_s32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 nla_put_u32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302954 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 goto fail;
2959
2960 nla_nest_end(skb, ap);
2961 }
2962 nla_nest_end(skb, aps);
2963
2964 if (nla_put_u8(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2966 pData->moreData))
2967 goto fail;
2968 }
2969
2970 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302971 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 return;
2973
2974fail:
2975 kfree_skb(skb);
2976 return;
2977
2978}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302980/**
2981 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2982 * Handle an SSID hotlist match event
2983 * @ctx: HDD context registered with SME
2984 * @event: The SSID hotlist match event
2985 *
2986 * This function will take an SSID match event that was generated by
2987 * firmware and will convert it into a cfg80211 vendor event which is
2988 * sent to userspace.
2989 *
2990 * Return: none
2991 */
2992static void
2993wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2994 void *pMsg)
2995{
2996 hdd_context_t *hdd_ctx = ctx;
2997 struct sk_buff *skb;
2998 tANI_U32 i, index;
2999 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3000
3001 ENTER();
3002
3003 if (wlan_hdd_validate_context(hdd_ctx)) {
3004 hddLog(LOGE,
3005 FL("HDD context is not valid or response"));
3006 return;
3007 }
3008 if (!pMsg)
3009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3011 return;
3012 }
3013
3014 if (pData->ssid_found) {
3015 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3016 hddLog(LOG1, "SSID hotlist found");
3017 } else {
3018 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3019 hddLog(LOG1, "SSID hotlist lost");
3020 }
3021
3022 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3024 NULL,
3025#endif
3026 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3027 index, GFP_KERNEL);
3028
3029 if (!skb) {
3030 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3031 return;
3032 }
3033 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3034 pData->requestId, pData->numHotlistSsid, pData->moreData);
3035
3036 for (i = 0; i < pData->numHotlistSsid; i++) {
3037 hddLog(LOG1, "[i=%d] Timestamp %llu "
3038 "Ssid: %s "
3039 "Bssid (" MAC_ADDRESS_STR ") "
3040 "Channel %u "
3041 "Rssi %d "
3042 "RTT %u "
3043 "RTT_SD %u",
3044 i,
3045 pData->ssidHotlist[i].ts,
3046 pData->ssidHotlist[i].ssid,
3047 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3048 pData->ssidHotlist[i].channel,
3049 pData->ssidHotlist[i].rssi,
3050 pData->ssidHotlist[i].rtt,
3051 pData->ssidHotlist[i].rtt_sd);
3052 }
3053
3054 if (nla_put_u32(skb,
3055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3056 pData->requestId) ||
3057 nla_put_u32(skb,
3058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3059 pData->numHotlistSsid)) {
3060 hddLog(LOGE, FL("put fail"));
3061 goto fail;
3062 }
3063
3064 if (pData->numHotlistSsid) {
3065 struct nlattr *aps;
3066 aps = nla_nest_start(skb,
3067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3068 if (!aps) {
3069 hddLog(LOGE, FL("nest fail"));
3070 goto fail;
3071 }
3072
3073 for (i = 0; i < pData->numHotlistSsid; i++) {
3074 struct nlattr *ap;
3075
3076 ap = nla_nest_start(skb, i);
3077 if (!ap) {
3078 hddLog(LOGE, FL("nest fail"));
3079 goto fail;
3080 }
3081
3082 if (nla_put_u64(skb,
3083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3084 pData->ssidHotlist[i].ts) ||
3085 nla_put(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3087 sizeof(pData->ssidHotlist[i].ssid),
3088 pData->ssidHotlist[i].ssid) ||
3089 nla_put(skb,
3090 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3091 sizeof(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].bssid) ||
3093 nla_put_u32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3095 pData->ssidHotlist[i].channel) ||
3096 nla_put_s32(skb,
3097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3098 pData->ssidHotlist[i].rssi) ||
3099 nla_put_u32(skb,
3100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3101 pData->ssidHotlist[i].rtt) ||
3102 nla_put_u32(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3104 pData->ssidHotlist[i].rtt_sd)) {
3105 hddLog(LOGE, FL("put fail"));
3106 goto fail;
3107 }
3108 nla_nest_end(skb, ap);
3109 }
3110 nla_nest_end(skb, aps);
3111
3112 if (nla_put_u8(skb,
3113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3114 pData->moreData)) {
3115 hddLog(LOGE, FL("put fail"));
3116 goto fail;
3117 }
3118 }
3119
3120 cfg80211_vendor_event(skb, GFP_KERNEL);
3121 return;
3122
3123fail:
3124 kfree_skb(skb);
3125 return;
3126
3127}
3128
3129
Dino Mycle6fb96c12014-06-10 11:52:40 +05303130static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3131 void *pMsg)
3132{
3133 struct sk_buff *skb;
3134 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3135 tpSirWifiFullScanResultEvent pData =
3136 (tpSirWifiFullScanResultEvent) (pMsg);
3137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303138 ENTER();
3139
3140 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303141 hddLog(LOGE,
3142 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 return;
3144 }
3145 if (!pMsg)
3146 {
3147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 return;
3149 }
3150
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303151 /*
3152 * If the full scan result including IE data exceeds NL 4K size
3153 * limitation, drop that beacon/probe rsp frame.
3154 */
3155 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3156 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3157 return;
3158 }
3159
Dino Mycle6fb96c12014-06-10 11:52:40 +05303160 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3162 NULL,
3163#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3166 GFP_KERNEL);
3167
3168 if (!skb) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("cfg80211_vendor_event_alloc failed"));
3171 return;
3172 }
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3177 "Ssid (%s)"
3178 "Bssid (" MAC_ADDRESS_STR ")"
3179 "Channel (%u)"
3180 "Rssi (%d)"
3181 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 "RTT_SD (%u)"
3183 "Bcn Period %d"
3184 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 pData->ap.ts,
3186 pData->ap.ssid,
3187 MAC_ADDR_ARRAY(pData->ap.bssid),
3188 pData->ap.channel,
3189 pData->ap.rssi,
3190 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303191 pData->ap.rtt_sd,
3192 pData->ap.beaconPeriod,
3193 pData->ap.capability);
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3196 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3197 pData->requestId) ||
3198 nla_put_u64(skb,
3199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3200 pData->ap.ts) ||
3201 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3202 sizeof(pData->ap.ssid),
3203 pData->ap.ssid) ||
3204 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3205 WNI_CFG_BSSID_LEN,
3206 pData->ap.bssid) ||
3207 nla_put_u32(skb,
3208 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3209 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303210 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211 pData->ap.rssi) ||
3212 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3213 pData->ap.rtt) ||
3214 nla_put_u32(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3216 pData->ap.rtt_sd) ||
3217 nla_put_u16(skb,
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3219 pData->ap.beaconPeriod) ||
3220 nla_put_u16(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3222 pData->ap.capability) ||
3223 nla_put_u32(skb,
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303225 pData->ieLength) ||
3226 nla_put_u8(skb,
3227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3228 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 {
3230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3231 goto nla_put_failure;
3232 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303233
3234 if (pData->ieLength) {
3235 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3236 pData->ieLength,
3237 pData->ie))
3238 {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3240 goto nla_put_failure;
3241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 }
3243
3244 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246 return;
3247
3248nla_put_failure:
3249 kfree_skb(skb);
3250 return;
3251}
3252
3253static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3254 void *pMsg)
3255{
3256 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3257 struct sk_buff *skb = NULL;
3258 tpSirEXTScanResultsAvailableIndParams pData =
3259 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303261 ENTER();
3262
3263 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264 hddLog(LOGE,
3265 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 return;
3267 }
3268 if (!pMsg)
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 return;
3272 }
3273
3274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3276 NULL,
3277#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3279 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3280 GFP_KERNEL);
3281
3282 if (!skb) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 FL("cfg80211_vendor_event_alloc failed"));
3285 return;
3286 }
3287
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3289 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3290 pData->numResultsAvailable);
3291 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3292 pData->requestId) ||
3293 nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3295 pData->numResultsAvailable)) {
3296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3297 goto nla_put_failure;
3298 }
3299
3300 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303
3304nla_put_failure:
3305 kfree_skb(skb);
3306 return;
3307}
3308
3309static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3310{
3311 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3312 struct sk_buff *skb = NULL;
3313 tpSirEXTScanProgressIndParams pData =
3314 (tpSirEXTScanProgressIndParams) pMsg;
3315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303316 ENTER();
3317
3318 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303319 hddLog(LOGE,
3320 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 return;
3322 }
3323 if (!pMsg)
3324 {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
3328
3329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3331 NULL,
3332#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3334 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3335 GFP_KERNEL);
3336
3337 if (!skb) {
3338 hddLog(VOS_TRACE_LEVEL_ERROR,
3339 FL("cfg80211_vendor_event_alloc failed"));
3340 return;
3341 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3344 pData->extScanEventType);
3345 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3346 pData->status);
3347
3348 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3349 pData->extScanEventType) ||
3350 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3352 pData->requestId) ||
3353 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3355 pData->status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3357 goto nla_put_failure;
3358 }
3359
3360 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 return;
3363
3364nla_put_failure:
3365 kfree_skb(skb);
3366 return;
3367}
3368
3369void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3370 void *pMsg)
3371{
3372 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303374 ENTER();
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 return;
3378 }
3379
3380 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3381
3382
3383 switch(evType) {
3384 case SIR_HAL_EXTSCAN_START_RSP:
3385 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3386 break;
3387
3388 case SIR_HAL_EXTSCAN_STOP_RSP:
3389 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3392 /* There is no need to send this response to upper layer
3393 Just log the message */
3394 hddLog(VOS_TRACE_LEVEL_INFO,
3395 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3396 break;
3397 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3398 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3399 break;
3400
3401 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3402 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3403 break;
3404
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303405 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3406 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3410 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3411 break;
3412
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303414 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415 break;
3416 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3417 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3420 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3423 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3424 break;
3425 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3426 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3427 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303428 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3429 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3430 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3432 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3433 break;
3434 default:
3435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3436 break;
3437 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303439}
3440
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303441static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3442 struct wireless_dev *wdev,
3443 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444{
Dino Myclee8843b32014-07-04 14:21:45 +05303445 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 struct net_device *dev = wdev->netdev;
3447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3448 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3449 struct nlattr
3450 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3451 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452 struct hdd_ext_scan_context *context;
3453 unsigned long rc;
3454 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 ENTER();
3457
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 status = wlan_hdd_validate_context(pHddCtx);
3459 if (0 != status)
3460 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 return -EINVAL;
3462 }
Dino Myclee8843b32014-07-04 14:21:45 +05303463 /* check the EXTScan Capability */
3464 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3465 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3466 {
3467 hddLog(VOS_TRACE_LEVEL_ERROR,
3468 FL("EXTScan not enabled/supported by Firmware"));
3469 return -EINVAL;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3473 data, dataLen,
3474 wlan_hdd_extscan_config_policy)) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3476 return -EINVAL;
3477 }
3478
3479 /* Parse and fetch request Id */
3480 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3482 return -EINVAL;
3483 }
3484
Dino Myclee8843b32014-07-04 14:21:45 +05303485 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303487 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488
Dino Myclee8843b32014-07-04 14:21:45 +05303489 reqMsg.sessionId = pAdapter->sessionId;
3490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303492 vos_spin_lock_acquire(&hdd_context_lock);
3493 context = &pHddCtx->ext_scan_context;
3494 context->request_id = reqMsg.requestId;
3495 INIT_COMPLETION(context->response_event);
3496 vos_spin_lock_release(&hdd_context_lock);
3497
Dino Myclee8843b32014-07-04 14:21:45 +05303498 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 if (!HAL_STATUS_SUCCESS(status)) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303504
3505 rc = wait_for_completion_timeout(&context->response_event,
3506 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3507 if (!rc) {
3508 hddLog(LOGE, FL("Target response timed out"));
3509 return -ETIMEDOUT;
3510 }
3511
3512 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3513 if (ret)
3514 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3515
3516 return ret;
3517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303518 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 return 0;
3520}
3521
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303522static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3523 struct wireless_dev *wdev,
3524 const void *data, int dataLen)
3525{
3526 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303528 vos_ssr_protect(__func__);
3529 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3530 vos_ssr_unprotect(__func__);
3531
3532 return ret;
3533}
3534
3535static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3536 struct wireless_dev *wdev,
3537 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538{
Dino Myclee8843b32014-07-04 14:21:45 +05303539 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 struct net_device *dev = wdev->netdev;
3541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3543 struct nlattr
3544 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3545 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 struct hdd_ext_scan_context *context;
3547 unsigned long rc;
3548 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 ENTER();
3551
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303552 if (VOS_FTM_MODE == hdd_get_conparam()) {
3553 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3554 return -EINVAL;
3555 }
3556
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 status = wlan_hdd_validate_context(pHddCtx);
3558 if (0 != status)
3559 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 return -EINVAL;
3561 }
Dino Myclee8843b32014-07-04 14:21:45 +05303562 /* check the EXTScan Capability */
3563 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3564 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3565 {
3566 hddLog(VOS_TRACE_LEVEL_ERROR,
3567 FL("EXTScan not enabled/supported by Firmware"));
3568 return -EINVAL;
3569 }
3570
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3572 data, dataLen,
3573 wlan_hdd_extscan_config_policy)) {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3575 return -EINVAL;
3576 }
3577 /* Parse and fetch request Id */
3578 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3580 return -EINVAL;
3581 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582
Dino Myclee8843b32014-07-04 14:21:45 +05303583 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3585
Dino Myclee8843b32014-07-04 14:21:45 +05303586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587
Dino Myclee8843b32014-07-04 14:21:45 +05303588 reqMsg.sessionId = pAdapter->sessionId;
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
3591 /* Parse and fetch flush parameter */
3592 if (!tb
3593 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3596 goto failed;
3597 }
Dino Myclee8843b32014-07-04 14:21:45 +05303598 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3600
Dino Myclee8843b32014-07-04 14:21:45 +05303601 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303603 spin_lock(&hdd_context_lock);
3604 context = &pHddCtx->ext_scan_context;
3605 context->request_id = reqMsg.requestId;
3606 context->ignore_cached_results = false;
3607 INIT_COMPLETION(context->response_event);
3608 spin_unlock(&hdd_context_lock);
3609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 if (!HAL_STATUS_SUCCESS(status)) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR,
3613 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303614 return -EINVAL;
3615 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616
3617 rc = wait_for_completion_timeout(&context->response_event,
3618 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3619 if (!rc) {
3620 hddLog(LOGE, FL("Target response timed out"));
3621 retval = -ETIMEDOUT;
3622 spin_lock(&hdd_context_lock);
3623 context->ignore_cached_results = true;
3624 spin_unlock(&hdd_context_lock);
3625 } else {
3626 spin_lock(&hdd_context_lock);
3627 retval = context->response_status;
3628 spin_unlock(&hdd_context_lock);
3629 }
3630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303631 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633
3634failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635 return -EINVAL;
3636}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303637static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3638 struct wireless_dev *wdev,
3639 const void *data, int dataLen)
3640{
3641 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303643 vos_ssr_protect(__func__);
3644 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3645 vos_ssr_unprotect(__func__);
3646
3647 return ret;
3648}
3649
3650static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303652 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653{
3654 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3655 struct net_device *dev = wdev->netdev;
3656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3658 struct nlattr
3659 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3660 struct nlattr
3661 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3662 struct nlattr *apTh;
3663 eHalStatus status;
3664 tANI_U8 i = 0;
3665 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303666 struct hdd_ext_scan_context *context;
3667 tANI_U32 request_id;
3668 unsigned long rc;
3669 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303671 ENTER();
3672
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303673 if (VOS_FTM_MODE == hdd_get_conparam()) {
3674 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3675 return -EINVAL;
3676 }
3677
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 status = wlan_hdd_validate_context(pHddCtx);
3679 if (0 != status)
3680 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681 return -EINVAL;
3682 }
Dino Myclee8843b32014-07-04 14:21:45 +05303683 /* check the EXTScan Capability */
3684 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3685 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3686 {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 FL("EXTScan not enabled/supported by Firmware"));
3689 return -EINVAL;
3690 }
3691
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3693 data, dataLen,
3694 wlan_hdd_extscan_config_policy)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3696 return -EINVAL;
3697 }
3698
3699 /* Parse and fetch request Id */
3700 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3702 return -EINVAL;
3703 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3705 vos_mem_malloc(sizeof(*pReqMsg));
3706 if (!pReqMsg) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3708 return -ENOMEM;
3709 }
3710
Dino Myclee8843b32014-07-04 14:21:45 +05303711
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 pReqMsg->requestId = nla_get_u32(
3713 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3715
3716 /* Parse and fetch number of APs */
3717 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3719 goto fail;
3720 }
3721
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303722 /* Parse and fetch lost ap sample size */
3723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3724 hddLog(LOGE, FL("attr lost ap sample size failed"));
3725 goto fail;
3726 }
3727
3728 pReqMsg->lostBssidSampleSize = nla_get_u32(
3729 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3730 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3731
Dino Mycle6fb96c12014-06-10 11:52:40 +05303732 pReqMsg->sessionId = pAdapter->sessionId;
3733 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3734
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303735 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738
3739 nla_for_each_nested(apTh,
3740 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3741 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3742 nla_data(apTh), nla_len(apTh),
3743 NULL)) {
3744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3745 goto fail;
3746 }
3747
3748 /* Parse and fetch MAC address */
3749 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3751 goto fail;
3752 }
3753 memcpy(pReqMsg->ap[i].bssid, nla_data(
3754 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3755 sizeof(tSirMacAddr));
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3757
3758 /* Parse and fetch low RSSI */
3759 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3761 goto fail;
3762 }
3763 pReqMsg->ap[i].low = nla_get_s32(
3764 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3765 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3766
3767 /* Parse and fetch high RSSI */
3768 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3770 goto fail;
3771 }
3772 pReqMsg->ap[i].high = nla_get_s32(
3773 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3774 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3775 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303776 i++;
3777 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303778
3779 context = &pHddCtx->ext_scan_context;
3780 spin_lock(&hdd_context_lock);
3781 INIT_COMPLETION(context->response_event);
3782 context->request_id = request_id = pReqMsg->requestId;
3783 spin_unlock(&hdd_context_lock);
3784
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3786 if (!HAL_STATUS_SUCCESS(status)) {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 FL("sme_SetBssHotlist failed(err=%d)"), status);
3789 vos_mem_free(pReqMsg);
3790 return -EINVAL;
3791 }
3792
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303793 /* request was sent -- wait for the response */
3794 rc = wait_for_completion_timeout(&context->response_event,
3795 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3796
3797 if (!rc) {
3798 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3799 retval = -ETIMEDOUT;
3800 } else {
3801 spin_lock(&hdd_context_lock);
3802 if (context->request_id == request_id)
3803 retval = context->response_status;
3804 else
3805 retval = -EINVAL;
3806 spin_unlock(&hdd_context_lock);
3807 }
3808
Dino Myclee8843b32014-07-04 14:21:45 +05303809 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303810 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303811 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
3813fail:
3814 vos_mem_free(pReqMsg);
3815 return -EINVAL;
3816}
3817
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303818static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3819 struct wireless_dev *wdev,
3820 const void *data, int dataLen)
3821{
3822 int ret = 0;
3823
3824 vos_ssr_protect(__func__);
3825 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3826 dataLen);
3827 vos_ssr_unprotect(__func__);
3828
3829 return ret;
3830}
3831
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303832/*
3833 * define short names for the global vendor params
3834 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3835 */
3836#define PARAM_MAX \
3837QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3838#define PARAM_REQUEST_ID \
3839QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3840#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3841QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3842#define PARAMS_NUM_SSID \
3843QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3844#define THRESHOLD_PARAM \
3845QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3846#define PARAM_SSID \
3847QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3848#define PARAM_BAND \
3849QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3850#define PARAM_RSSI_LOW \
3851QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3852#define PARAM_RSSI_HIGH \
3853QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3854
3855/**
3856 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3857 * @wiphy: Pointer to wireless phy
3858 * @wdev: Pointer to wireless device
3859 * @data: Pointer to data
3860 * @data_len: Data length
3861 *
3862 * Return: 0 on success, negative errno on failure
3863 */
3864static int
3865__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3866 struct wireless_dev *wdev,
3867 const void *data,
3868 int data_len)
3869{
3870 tSirEXTScanSetSsidHotListReqParams *request;
3871 struct net_device *dev = wdev->netdev;
3872 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3873 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3874 struct nlattr *tb[PARAM_MAX + 1];
3875 struct nlattr *tb2[PARAM_MAX + 1];
3876 struct nlattr *ssids;
3877 struct hdd_ext_scan_context *context;
3878 uint32_t request_id;
3879 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3880 int ssid_len;
3881 eHalStatus status;
3882 int i, rem, retval;
3883 unsigned long rc;
3884
3885 ENTER();
3886
3887 if (VOS_FTM_MODE == hdd_get_conparam()) {
3888 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3889 return -EINVAL;
3890 }
3891
3892 retval = wlan_hdd_validate_context(hdd_ctx);
3893 if (0 != retval) {
3894 hddLog(LOGE, FL("HDD context is not valid"));
3895 return -EINVAL;
3896 }
3897
3898 /* check the EXTScan Capability */
3899 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3900 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3901 {
3902 hddLog(VOS_TRACE_LEVEL_ERROR,
3903 FL("EXTScan not enabled/supported by Firmware"));
3904 return -EINVAL;
3905 }
3906
3907 if (nla_parse(tb, PARAM_MAX,
3908 data, data_len,
3909 wlan_hdd_extscan_config_policy)) {
3910 hddLog(LOGE, FL("Invalid ATTR"));
3911 return -EINVAL;
3912 }
3913
3914 request = vos_mem_malloc(sizeof(*request));
3915 if (!request) {
3916 hddLog(LOGE, FL("vos_mem_malloc failed"));
3917 return -ENOMEM;
3918 }
3919
3920 /* Parse and fetch request Id */
3921 if (!tb[PARAM_REQUEST_ID]) {
3922 hddLog(LOGE, FL("attr request id failed"));
3923 goto fail;
3924 }
3925
3926 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3927 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3928
3929 /* Parse and fetch lost SSID sample size */
3930 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3931 hddLog(LOGE, FL("attr number of Ssid failed"));
3932 goto fail;
3933 }
3934 request->lost_ssid_sample_size =
3935 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3936 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3937 request->lost_ssid_sample_size);
3938
3939 /* Parse and fetch number of hotlist SSID */
3940 if (!tb[PARAMS_NUM_SSID]) {
3941 hddLog(LOGE, FL("attr number of Ssid failed"));
3942 goto fail;
3943 }
3944 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3945 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3946
3947 request->session_id = adapter->sessionId;
3948 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3949
3950 i = 0;
3951 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3952 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3953 hddLog(LOGE,
3954 FL("Too Many SSIDs, %d exceeds %d"),
3955 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3956 break;
3957 }
3958 if (nla_parse(tb2, PARAM_MAX,
3959 nla_data(ssids), nla_len(ssids),
3960 wlan_hdd_extscan_config_policy)) {
3961 hddLog(LOGE, FL("nla_parse failed"));
3962 goto fail;
3963 }
3964
3965 /* Parse and fetch SSID */
3966 if (!tb2[PARAM_SSID]) {
3967 hddLog(LOGE, FL("attr ssid failed"));
3968 goto fail;
3969 }
3970 nla_memcpy(ssid_string,
3971 tb2[PARAM_SSID],
3972 sizeof(ssid_string));
3973 hddLog(LOG1, FL("SSID %s"),
3974 ssid_string);
3975 ssid_len = strlen(ssid_string);
3976 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3977 request->ssid[i].ssid.length = ssid_len;
3978 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3979 hddLog(LOG1, FL("After copying SSID %s"),
3980 request->ssid[i].ssid.ssId);
3981 hddLog(LOG1, FL("After copying length: %d"),
3982 ssid_len);
3983
3984 /* Parse and fetch low RSSI */
3985 if (!tb2[PARAM_BAND]) {
3986 hddLog(LOGE, FL("attr band failed"));
3987 goto fail;
3988 }
3989 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3990 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3991
3992 /* Parse and fetch low RSSI */
3993 if (!tb2[PARAM_RSSI_LOW]) {
3994 hddLog(LOGE, FL("attr low RSSI failed"));
3995 goto fail;
3996 }
3997 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3998 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3999
4000 /* Parse and fetch high RSSI */
4001 if (!tb2[PARAM_RSSI_HIGH]) {
4002 hddLog(LOGE, FL("attr high RSSI failed"));
4003 goto fail;
4004 }
4005 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4006 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4007 i++;
4008 }
4009
4010 context = &hdd_ctx->ext_scan_context;
4011 spin_lock(&hdd_context_lock);
4012 INIT_COMPLETION(context->response_event);
4013 context->request_id = request_id = request->request_id;
4014 spin_unlock(&hdd_context_lock);
4015
4016 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4017 if (!HAL_STATUS_SUCCESS(status)) {
4018 hddLog(LOGE,
4019 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4020 goto fail;
4021 }
4022
4023 vos_mem_free(request);
4024
4025 /* request was sent -- wait for the response */
4026 rc = wait_for_completion_timeout(&context->response_event,
4027 msecs_to_jiffies
4028 (WLAN_WAIT_TIME_EXTSCAN));
4029 if (!rc) {
4030 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4031 retval = -ETIMEDOUT;
4032 } else {
4033 spin_lock(&hdd_context_lock);
4034 if (context->request_id == request_id)
4035 retval = context->response_status;
4036 else
4037 retval = -EINVAL;
4038 spin_unlock(&hdd_context_lock);
4039 }
4040
4041 return retval;
4042
4043fail:
4044 vos_mem_free(request);
4045 return -EINVAL;
4046}
4047
4048/*
4049 * done with short names for the global vendor params
4050 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4051 */
4052#undef PARAM_MAX
4053#undef PARAM_REQUEST_ID
4054#undef PARAMS_NUM_SSID
4055#undef THRESHOLD_PARAM
4056#undef PARAM_SSID
4057#undef PARAM_BAND
4058#undef PARAM_RSSI_LOW
4059#undef PARAM_RSSI_HIGH
4060
4061static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4062 struct wireless_dev *wdev,
4063 const void *data, int dataLen)
4064{
4065 int ret = 0;
4066
4067 vos_ssr_protect(__func__);
4068 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4069 dataLen);
4070 vos_ssr_unprotect(__func__);
4071
4072 return ret;
4073}
4074
4075static int
4076__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4077 struct wireless_dev *wdev,
4078 const void *data,
4079 int data_len)
4080{
4081 tSirEXTScanResetSsidHotlistReqParams request;
4082 struct net_device *dev = wdev->netdev;
4083 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4084 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4085 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4086 struct hdd_ext_scan_context *context;
4087 uint32_t request_id;
4088 eHalStatus status;
4089 int retval;
4090 unsigned long rc;
4091
4092 ENTER();
4093
4094 if (VOS_FTM_MODE == hdd_get_conparam()) {
4095 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4096 return -EINVAL;
4097 }
4098
4099 retval = wlan_hdd_validate_context(hdd_ctx);
4100 if (0 != retval) {
4101 hddLog(LOGE, FL("HDD context is not valid"));
4102 return -EINVAL;
4103 }
4104
4105 /* check the EXTScan Capability */
4106 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4107 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4108 {
4109 hddLog(LOGE,
4110 FL("EXTScan not enabled/supported by Firmware"));
4111 return -EINVAL;
4112 }
4113
4114 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4115 data, data_len,
4116 wlan_hdd_extscan_config_policy)) {
4117 hddLog(LOGE, FL("Invalid ATTR"));
4118 return -EINVAL;
4119 }
4120
4121 /* Parse and fetch request Id */
4122 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4123 hddLog(LOGE, FL("attr request id failed"));
4124 return -EINVAL;
4125 }
4126
4127 request.requestId = nla_get_u32(
4128 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4129 request.sessionId = adapter->sessionId;
4130 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4131 request.sessionId);
4132
4133 context = &hdd_ctx->ext_scan_context;
4134 spin_lock(&hdd_context_lock);
4135 INIT_COMPLETION(context->response_event);
4136 context->request_id = request_id = request.requestId;
4137 spin_unlock(&hdd_context_lock);
4138
4139 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4140 if (!HAL_STATUS_SUCCESS(status)) {
4141 hddLog(LOGE,
4142 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4143 return -EINVAL;
4144 }
4145
4146 /* request was sent -- wait for the response */
4147 rc = wait_for_completion_timeout(&context->response_event,
4148 msecs_to_jiffies
4149 (WLAN_WAIT_TIME_EXTSCAN));
4150 if (!rc) {
4151 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4152 retval = -ETIMEDOUT;
4153 } else {
4154 spin_lock(&hdd_context_lock);
4155 if (context->request_id == request_id)
4156 retval = context->response_status;
4157 else
4158 retval = -EINVAL;
4159 spin_unlock(&hdd_context_lock);
4160 }
4161
4162 return retval;
4163}
4164
4165static int
4166wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4167 struct wireless_dev *wdev,
4168 const void *data,
4169 int data_len)
4170{
4171 int ret;
4172
4173 vos_ssr_protect(__func__);
4174 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4175 data, data_len);
4176 vos_ssr_unprotect(__func__);
4177
4178 return ret;
4179}
4180
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304181static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304183 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304184{
4185 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4186 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4187 tANI_U8 numChannels = 0;
4188 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304189 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 tWifiBand wifiBand;
4191 eHalStatus status;
4192 struct sk_buff *replySkb;
4193 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304194 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198 status = wlan_hdd_validate_context(pHddCtx);
4199 if (0 != status)
4200 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 return -EINVAL;
4202 }
Dino Myclee8843b32014-07-04 14:21:45 +05304203
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4205 data, dataLen,
4206 wlan_hdd_extscan_config_policy)) {
4207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4208 return -EINVAL;
4209 }
4210
4211 /* Parse and fetch request Id */
4212 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4214 return -EINVAL;
4215 }
4216 requestId = nla_get_u32(
4217 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4219
4220 /* Parse and fetch wifi band */
4221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4222 {
4223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4224 return -EINVAL;
4225 }
4226 wifiBand = nla_get_u32(
4227 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4229
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304230 /* Parse and fetch max channels */
4231 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4232 {
4233 hddLog(LOGE, FL("attr max channels failed"));
4234 return -EINVAL;
4235 }
4236 maxChannels = nla_get_u32(
4237 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4239
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4241 wifiBand, ChannelList,
4242 &numChannels);
4243 if (eHAL_STATUS_SUCCESS != status) {
4244 hddLog(VOS_TRACE_LEVEL_ERROR,
4245 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4246 return -EINVAL;
4247 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304248
4249 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304251
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252 for (i = 0; i < numChannels; i++)
4253 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4254
4255 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4256 sizeof(u32) * numChannels +
4257 NLMSG_HDRLEN);
4258
4259 if (!replySkb) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
4261 FL("valid channels: buffer alloc fail"));
4262 return -EINVAL;
4263 }
4264 if (nla_put_u32(replySkb,
4265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4266 numChannels) ||
4267 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4268 sizeof(u32) * numChannels, ChannelList)) {
4269
4270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4271 kfree_skb(replySkb);
4272 return -EINVAL;
4273 }
4274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304275 ret = cfg80211_vendor_cmd_reply(replySkb);
4276
4277 EXIT();
4278 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304279}
4280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304281static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4282 struct wireless_dev *wdev,
4283 const void *data, int dataLen)
4284{
4285 int ret = 0;
4286
4287 vos_ssr_protect(__func__);
4288 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4289 dataLen);
4290 vos_ssr_unprotect(__func__);
4291
4292 return ret;
4293}
4294
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304295static int hdd_extscan_start_fill_bucket_channel_spec(
4296 hdd_context_t *pHddCtx,
4297 tpSirEXTScanStartReqParams pReqMsg,
4298 struct nlattr **tb)
4299{
4300 struct nlattr *bucket[
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4302 struct nlattr *channel[
4303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4304 struct nlattr *buckets;
4305 struct nlattr *channels;
4306 int rem1, rem2;
4307 eHalStatus status;
4308 tANI_U8 bktIndex, j, numChannels;
4309 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4310 tANI_U32 passive_max_chn_time, active_max_chn_time;
4311
4312 bktIndex = 0;
4313
4314 nla_for_each_nested(buckets,
4315 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4316 if (nla_parse(bucket,
4317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4318 nla_data(buckets), nla_len(buckets), NULL)) {
4319 hddLog(LOGE, FL("nla_parse failed"));
4320 return -EINVAL;
4321 }
4322
4323 /* Parse and fetch bucket spec */
4324 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4325 hddLog(LOGE, FL("attr bucket index failed"));
4326 return -EINVAL;
4327 }
4328 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4329 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4330 hddLog(LOG1, FL("Bucket spec Index %d"),
4331 pReqMsg->buckets[bktIndex].bucket);
4332
4333 /* Parse and fetch wifi band */
4334 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4335 hddLog(LOGE, FL("attr wifi band failed"));
4336 return -EINVAL;
4337 }
4338 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4339 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4340 hddLog(LOG1, FL("Wifi band %d"),
4341 pReqMsg->buckets[bktIndex].band);
4342
4343 /* Parse and fetch period */
4344 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4345 hddLog(LOGE, FL("attr period failed"));
4346 return -EINVAL;
4347 }
4348 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4349 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4350 hddLog(LOG1, FL("period %d"),
4351 pReqMsg->buckets[bktIndex].period);
4352
4353 /* Parse and fetch report events */
4354 if (!bucket[
4355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4356 hddLog(LOGE, FL("attr report events failed"));
4357 return -EINVAL;
4358 }
4359 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4360 bucket[
4361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4362 hddLog(LOG1, FL("report events %d"),
4363 pReqMsg->buckets[bktIndex].reportEvents);
4364
4365 /* Parse and fetch max period */
4366 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4367 hddLog(LOGE, FL("attr max period failed"));
4368 return -EINVAL;
4369 }
4370 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4371 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4372 hddLog(LOG1, FL("max period %u"),
4373 pReqMsg->buckets[bktIndex].max_period);
4374
4375 /* Parse and fetch exponent */
4376 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4377 hddLog(LOGE, FL("attr exponent failed"));
4378 return -EINVAL;
4379 }
4380 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4381 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4382 hddLog(LOG1, FL("exponent %u"),
4383 pReqMsg->buckets[bktIndex].exponent);
4384
4385 /* Parse and fetch step count */
4386 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4387 hddLog(LOGE, FL("attr step count failed"));
4388 return -EINVAL;
4389 }
4390 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4391 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4392 hddLog(LOG1, FL("Step count %u"),
4393 pReqMsg->buckets[bktIndex].step_count);
4394
4395 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4396 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4397
4398 /* Framework shall pass the channel list if the input WiFi band is
4399 * WIFI_BAND_UNSPECIFIED.
4400 * If the input WiFi band is specified (any value other than
4401 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4402 */
4403 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4404 numChannels = 0;
4405 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4406 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4407 pReqMsg->buckets[bktIndex].band,
4408 chanList, &numChannels);
4409 if (!HAL_STATUS_SUCCESS(status)) {
4410 hddLog(LOGE,
4411 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4412 status);
4413 return -EINVAL;
4414 }
4415
4416 pReqMsg->buckets[bktIndex].numChannels =
4417 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4418 hddLog(LOG1, FL("Num channels %d"),
4419 pReqMsg->buckets[bktIndex].numChannels);
4420
4421 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4422 j++) {
4423 pReqMsg->buckets[bktIndex].channels[j].channel =
4424 chanList[j];
4425 pReqMsg->buckets[bktIndex].channels[j].
4426 chnlClass = 0;
4427 if (CSR_IS_CHANNEL_DFS(
4428 vos_freq_to_chan(chanList[j]))) {
4429 pReqMsg->buckets[bktIndex].channels[j].
4430 passive = 1;
4431 pReqMsg->buckets[bktIndex].channels[j].
4432 dwellTimeMs = passive_max_chn_time;
4433 } else {
4434 pReqMsg->buckets[bktIndex].channels[j].
4435 passive = 0;
4436 pReqMsg->buckets[bktIndex].channels[j].
4437 dwellTimeMs = active_max_chn_time;
4438 }
4439
4440 hddLog(LOG1,
4441 "Channel %u Passive %u Dwell time %u ms",
4442 pReqMsg->buckets[bktIndex].channels[j].channel,
4443 pReqMsg->buckets[bktIndex].channels[j].passive,
4444 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4445 }
4446
4447 bktIndex++;
4448 continue;
4449 }
4450
4451 /* Parse and fetch number of channels */
4452 if (!bucket[
4453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4454 hddLog(LOGE, FL("attr num channels failed"));
4455 return -EINVAL;
4456 }
4457
4458 pReqMsg->buckets[bktIndex].numChannels =
4459 nla_get_u32(bucket[
4460 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4461 hddLog(LOG1, FL("num channels %d"),
4462 pReqMsg->buckets[bktIndex].numChannels);
4463
4464 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4465 hddLog(LOGE, FL("attr channel spec failed"));
4466 return -EINVAL;
4467 }
4468
4469 j = 0;
4470 nla_for_each_nested(channels,
4471 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4472 if (nla_parse(channel,
4473 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4474 nla_data(channels), nla_len(channels),
4475 wlan_hdd_extscan_config_policy)) {
4476 hddLog(LOGE, FL("nla_parse failed"));
4477 return -EINVAL;
4478 }
4479
4480 /* Parse and fetch channel */
4481 if (!channel[
4482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4483 hddLog(LOGE, FL("attr channel failed"));
4484 return -EINVAL;
4485 }
4486 pReqMsg->buckets[bktIndex].channels[j].channel =
4487 nla_get_u32(channel[
4488 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4489 hddLog(LOG1, FL("channel %u"),
4490 pReqMsg->buckets[bktIndex].channels[j].channel);
4491
4492 /* Parse and fetch dwell time */
4493 if (!channel[
4494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4495 hddLog(LOGE, FL("attr dwelltime failed"));
4496 return -EINVAL;
4497 }
4498 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4499 nla_get_u32(channel[
4500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4501
4502 hddLog(LOG1, FL("Dwell time (%u ms)"),
4503 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4504
4505
4506 /* Parse and fetch channel spec passive */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4509 hddLog(LOGE,
4510 FL("attr channel spec passive failed"));
4511 return -EINVAL;
4512 }
4513 pReqMsg->buckets[bktIndex].channels[j].passive =
4514 nla_get_u8(channel[
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4516 hddLog(LOG1, FL("Chnl spec passive %u"),
4517 pReqMsg->buckets[bktIndex].channels[j].passive);
4518
4519 j++;
4520 }
4521
4522 bktIndex++;
4523 }
4524
4525 return 0;
4526}
4527
4528
4529/*
4530 * define short names for the global vendor params
4531 * used by wlan_hdd_cfg80211_extscan_start()
4532 */
4533#define PARAM_MAX \
4534QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4535#define PARAM_REQUEST_ID \
4536QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4537#define PARAM_BASE_PERIOD \
4538QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4539#define PARAM_MAX_AP_PER_SCAN \
4540QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4541#define PARAM_RPT_THRHLD_PERCENT \
4542QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4543#define PARAM_RPT_THRHLD_NUM_SCANS \
4544QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4545#define PARAM_NUM_BUCKETS \
4546QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4547
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304548static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304550 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551{
Dino Myclee8843b32014-07-04 14:21:45 +05304552 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304553 struct net_device *dev = wdev->netdev;
4554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4555 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4556 struct nlattr *tb[PARAM_MAX + 1];
4557 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304558 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304559 tANI_U32 request_id;
4560 struct hdd_ext_scan_context *context;
4561 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304562
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304563 ENTER();
4564
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304565 if (VOS_FTM_MODE == hdd_get_conparam()) {
4566 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4567 return -EINVAL;
4568 }
4569
Dino Mycle6fb96c12014-06-10 11:52:40 +05304570 status = wlan_hdd_validate_context(pHddCtx);
4571 if (0 != status)
4572 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304573 return -EINVAL;
4574 }
Dino Myclee8843b32014-07-04 14:21:45 +05304575 /* check the EXTScan Capability */
4576 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4577 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4578 {
4579 hddLog(VOS_TRACE_LEVEL_ERROR,
4580 FL("EXTScan not enabled/supported by Firmware"));
4581 return -EINVAL;
4582 }
4583
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304584 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 data, dataLen,
4586 wlan_hdd_extscan_config_policy)) {
4587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4588 return -EINVAL;
4589 }
4590
4591 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304592 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4594 return -EINVAL;
4595 }
4596
Dino Myclee8843b32014-07-04 14:21:45 +05304597 pReqMsg = (tpSirEXTScanStartReqParams)
4598 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4601 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 }
4603
4604 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304605 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4607
4608 pReqMsg->sessionId = pAdapter->sessionId;
4609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4610
4611 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304612 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4614 goto fail;
4615 }
4616 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304617 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304618 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4619 pReqMsg->basePeriod);
4620
4621 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304622 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4624 goto fail;
4625 }
4626 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304627 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4629 pReqMsg->maxAPperScan);
4630
4631 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4634 goto fail;
4635 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 pReqMsg->reportThresholdPercent = nla_get_u8(
4637 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 pReqMsg->reportThresholdPercent);
4640
4641 /* Parse and fetch report threshold num scans */
4642 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4643 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4644 goto fail;
4645 }
4646 pReqMsg->reportThresholdNumScans = nla_get_u8(
4647 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4648 hddLog(LOG1, FL("Report Threshold num scans %d"),
4649 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650
4651 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304652 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4654 goto fail;
4655 }
4656 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4659 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4660 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4661 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4662 }
4663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4664 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4668 goto fail;
4669 }
4670
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4674 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304675
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304676 context = &pHddCtx->ext_scan_context;
4677 spin_lock(&hdd_context_lock);
4678 INIT_COMPLETION(context->response_event);
4679 context->request_id = request_id = pReqMsg->requestId;
4680 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304681
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4683 if (!HAL_STATUS_SUCCESS(status)) {
4684 hddLog(VOS_TRACE_LEVEL_ERROR,
4685 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304686 goto fail;
4687 }
4688
4689 /* request was sent -- wait for the response */
4690 rc = wait_for_completion_timeout(&context->response_event,
4691 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4692
4693 if (!rc) {
4694 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4695 retval = -ETIMEDOUT;
4696 } else {
4697 spin_lock(&hdd_context_lock);
4698 if (context->request_id == request_id)
4699 retval = context->response_status;
4700 else
4701 retval = -EINVAL;
4702 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 }
4704
Dino Myclee8843b32014-07-04 14:21:45 +05304705 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304706 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708
4709fail:
4710 vos_mem_free(pReqMsg);
4711 return -EINVAL;
4712}
4713
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714/*
4715 * done with short names for the global vendor params
4716 * used by wlan_hdd_cfg80211_extscan_start()
4717 */
4718#undef PARAM_MAX
4719#undef PARAM_REQUEST_ID
4720#undef PARAM_BASE_PERIOD
4721#undef PARAMS_MAX_AP_PER_SCAN
4722#undef PARAMS_RPT_THRHLD_PERCENT
4723#undef PARAMS_RPT_THRHLD_NUM_SCANS
4724#undef PARAMS_NUM_BUCKETS
4725
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304726static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4727 struct wireless_dev *wdev,
4728 const void *data, int dataLen)
4729{
4730 int ret = 0;
4731
4732 vos_ssr_protect(__func__);
4733 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4734 vos_ssr_unprotect(__func__);
4735
4736 return ret;
4737}
4738
4739static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304741 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742{
Dino Myclee8843b32014-07-04 14:21:45 +05304743 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 struct net_device *dev = wdev->netdev;
4745 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4747 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4748 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304749 int retval;
4750 unsigned long rc;
4751 struct hdd_ext_scan_context *context;
4752 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304754 ENTER();
4755
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304756 if (VOS_FTM_MODE == hdd_get_conparam()) {
4757 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4758 return -EINVAL;
4759 }
4760
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 status = wlan_hdd_validate_context(pHddCtx);
4762 if (0 != status)
4763 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 return -EINVAL;
4765 }
Dino Myclee8843b32014-07-04 14:21:45 +05304766 /* check the EXTScan Capability */
4767 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4768 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4769 {
4770 hddLog(VOS_TRACE_LEVEL_ERROR,
4771 FL("EXTScan not enabled/supported by Firmware"));
4772 return -EINVAL;
4773 }
4774
Dino Mycle6fb96c12014-06-10 11:52:40 +05304775 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4776 data, dataLen,
4777 wlan_hdd_extscan_config_policy)) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4779 return -EINVAL;
4780 }
4781
4782 /* Parse and fetch request Id */
4783 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4785 return -EINVAL;
4786 }
4787
Dino Myclee8843b32014-07-04 14:21:45 +05304788 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791
Dino Myclee8843b32014-07-04 14:21:45 +05304792 reqMsg.sessionId = pAdapter->sessionId;
4793 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304795 context = &pHddCtx->ext_scan_context;
4796 spin_lock(&hdd_context_lock);
4797 INIT_COMPLETION(context->response_event);
4798 context->request_id = request_id = reqMsg.sessionId;
4799 spin_unlock(&hdd_context_lock);
4800
Dino Myclee8843b32014-07-04 14:21:45 +05304801 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 if (!HAL_STATUS_SUCCESS(status)) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR,
4804 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 return -EINVAL;
4806 }
4807
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304808 /* request was sent -- wait for the response */
4809 rc = wait_for_completion_timeout(&context->response_event,
4810 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4811
4812 if (!rc) {
4813 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4814 retval = -ETIMEDOUT;
4815 } else {
4816 spin_lock(&hdd_context_lock);
4817 if (context->request_id == request_id)
4818 retval = context->response_status;
4819 else
4820 retval = -EINVAL;
4821 spin_unlock(&hdd_context_lock);
4822 }
4823
4824 return retval;
4825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304826 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304827 return 0;
4828}
4829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304830static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4831 struct wireless_dev *wdev,
4832 const void *data, int dataLen)
4833{
4834 int ret = 0;
4835
4836 vos_ssr_protect(__func__);
4837 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4838 vos_ssr_unprotect(__func__);
4839
4840 return ret;
4841}
4842
4843static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304845 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304846{
Dino Myclee8843b32014-07-04 14:21:45 +05304847 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 struct net_device *dev = wdev->netdev;
4849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4851 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4852 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304853 struct hdd_ext_scan_context *context;
4854 tANI_U32 request_id;
4855 unsigned long rc;
4856 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304858 ENTER();
4859
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304860 if (VOS_FTM_MODE == hdd_get_conparam()) {
4861 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4862 return -EINVAL;
4863 }
4864
Dino Mycle6fb96c12014-06-10 11:52:40 +05304865 status = wlan_hdd_validate_context(pHddCtx);
4866 if (0 != status)
4867 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304868 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304869 return -EINVAL;
4870 }
Dino Myclee8843b32014-07-04 14:21:45 +05304871 /* check the EXTScan Capability */
4872 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4873 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4874 {
4875 hddLog(VOS_TRACE_LEVEL_ERROR,
4876 FL("EXTScan not enabled/supported by Firmware"));
4877 return -EINVAL;
4878 }
4879
Dino Mycle6fb96c12014-06-10 11:52:40 +05304880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4881 data, dataLen,
4882 wlan_hdd_extscan_config_policy)) {
4883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4884 return -EINVAL;
4885 }
4886
4887 /* Parse and fetch request Id */
4888 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4890 return -EINVAL;
4891 }
4892
Dino Myclee8843b32014-07-04 14:21:45 +05304893 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896
Dino Myclee8843b32014-07-04 14:21:45 +05304897 reqMsg.sessionId = pAdapter->sessionId;
4898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304900 context = &pHddCtx->ext_scan_context;
4901 spin_lock(&hdd_context_lock);
4902 INIT_COMPLETION(context->response_event);
4903 context->request_id = request_id = reqMsg.requestId;
4904 spin_unlock(&hdd_context_lock);
4905
Dino Myclee8843b32014-07-04 14:21:45 +05304906 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 if (!HAL_STATUS_SUCCESS(status)) {
4908 hddLog(VOS_TRACE_LEVEL_ERROR,
4909 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304910 return -EINVAL;
4911 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304912
4913 /* request was sent -- wait for the response */
4914 rc = wait_for_completion_timeout(&context->response_event,
4915 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4916 if (!rc) {
4917 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4918 retval = -ETIMEDOUT;
4919 } else {
4920 spin_lock(&hdd_context_lock);
4921 if (context->request_id == request_id)
4922 retval = context->response_status;
4923 else
4924 retval = -EINVAL;
4925 spin_unlock(&hdd_context_lock);
4926 }
4927
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304928 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930}
4931
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304932static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4933 struct wireless_dev *wdev,
4934 const void *data, int dataLen)
4935{
4936 int ret = 0;
4937
4938 vos_ssr_protect(__func__);
4939 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4940 vos_ssr_unprotect(__func__);
4941
4942 return ret;
4943}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304944#endif /* WLAN_FEATURE_EXTSCAN */
4945
Atul Mittal115287b2014-07-08 13:26:33 +05304946/*EXT TDLS*/
4947static const struct nla_policy
4948wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4949{
4950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4953 {.type = NLA_S32 },
4954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4956
4957};
4958
4959static const struct nla_policy
4960wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4961{
4962 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4963
4964};
4965
4966static const struct nla_policy
4967wlan_hdd_tdls_config_state_change_policy[
4968 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4969{
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4975 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304976
4977};
4978
4979static const struct nla_policy
4980wlan_hdd_tdls_config_get_status_policy[
4981 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4982{
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4988 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304989
4990};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304991
4992static const struct nla_policy
4993wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4994{
4995 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4996};
4997
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304998static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304999 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305000 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305001 int data_len)
5002{
5003
5004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5005 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305007 ENTER();
5008
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305010 return -EINVAL;
5011 }
5012 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305013 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305014 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305015 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305016 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305017 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305018 return -ENOTSUPP;
5019 }
5020
5021 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5022 data, data_len, wlan_hdd_mac_config)) {
5023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5024 return -EINVAL;
5025 }
5026
5027 /* Parse and fetch mac address */
5028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5030 return -EINVAL;
5031 }
5032
5033 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5034 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5035 VOS_MAC_ADDR_LAST_3_BYTES);
5036
Siddharth Bhal76972212014-10-15 16:22:51 +05305037 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5038
5039 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5041 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305042 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5044 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5045 {
5046 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5047 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5048 VOS_MAC_ADDRESS_LEN);
5049 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305050 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051
Siddharth Bhal76972212014-10-15 16:22:51 +05305052 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5053 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305054 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5055 }
5056
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305057 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 return 0;
5059}
5060
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305061static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5062 struct wireless_dev *wdev,
5063 const void *data,
5064 int data_len)
5065{
5066 int ret = 0;
5067
5068 vos_ssr_protect(__func__);
5069 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5070 vos_ssr_unprotect(__func__);
5071
5072 return ret;
5073}
5074
5075static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305076 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305077 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305078 int data_len)
5079{
5080 u8 peer[6] = {0};
5081 struct net_device *dev = wdev->netdev;
5082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5084 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5085 eHalStatus ret;
5086 tANI_S32 state;
5087 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305088 tANI_S32 global_operating_class = 0;
5089 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305090 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305091 int retVal;
5092
5093 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305094
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305095 if (!pAdapter) {
5096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5097 return -EINVAL;
5098 }
5099
Atul Mittal115287b2014-07-08 13:26:33 +05305100 ret = wlan_hdd_validate_context(pHddCtx);
5101 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305103 return -EINVAL;
5104 }
5105 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305107 return -ENOTSUPP;
5108 }
5109 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5110 data, data_len,
5111 wlan_hdd_tdls_config_get_status_policy)) {
5112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5113 return -EINVAL;
5114 }
5115
5116 /* Parse and fetch mac address */
5117 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5119 return -EINVAL;
5120 }
5121
5122 memcpy(peer, nla_data(
5123 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5124 sizeof(peer));
5125 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5126
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305127 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305130 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305131 NLMSG_HDRLEN);
5132
5133 if (!skb) {
5134 hddLog(VOS_TRACE_LEVEL_ERROR,
5135 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5136 return -EINVAL;
5137 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305139 reason,
5140 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305141 global_operating_class,
5142 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305143 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305144 if (nla_put_s32(skb,
5145 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5146 state) ||
5147 nla_put_s32(skb,
5148 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5149 reason) ||
5150 nla_put_s32(skb,
5151 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5152 global_operating_class) ||
5153 nla_put_s32(skb,
5154 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5155 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305156
5157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5158 goto nla_put_failure;
5159 }
5160
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305161 retVal = cfg80211_vendor_cmd_reply(skb);
5162 EXIT();
5163 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305164
5165nla_put_failure:
5166 kfree_skb(skb);
5167 return -EINVAL;
5168}
5169
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305170static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5171 struct wireless_dev *wdev,
5172 const void *data,
5173 int data_len)
5174{
5175 int ret = 0;
5176
5177 vos_ssr_protect(__func__);
5178 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5179 vos_ssr_unprotect(__func__);
5180
5181 return ret;
5182}
5183
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305184static int wlan_hdd_cfg80211_exttdls_callback(
5185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5186 const tANI_U8* mac,
5187#else
5188 tANI_U8* mac,
5189#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305190 tANI_S32 state,
5191 tANI_S32 reason,
5192 void *ctx)
5193{
5194 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305195 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 tANI_S32 global_operating_class = 0;
5197 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305198 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305200 ENTER();
5201
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305202 if (!pAdapter) {
5203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5204 return -EINVAL;
5205 }
5206
5207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305208 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305210 return -EINVAL;
5211 }
5212
5213 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305215 return -ENOTSUPP;
5216 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305217 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5219 NULL,
5220#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305221 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5222 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5223 GFP_KERNEL);
5224
5225 if (!skb) {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,
5227 FL("cfg80211_vendor_event_alloc failed"));
5228 return -EINVAL;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305231 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5232 reason,
5233 state,
5234 global_operating_class,
5235 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305236 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5237 MAC_ADDR_ARRAY(mac));
5238
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305239 if (nla_put(skb,
5240 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5241 VOS_MAC_ADDR_SIZE, mac) ||
5242 nla_put_s32(skb,
5243 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5244 state) ||
5245 nla_put_s32(skb,
5246 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5247 reason) ||
5248 nla_put_s32(skb,
5249 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5250 channel) ||
5251 nla_put_s32(skb,
5252 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5253 global_operating_class)
5254 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5256 goto nla_put_failure;
5257 }
5258
5259 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305260 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305261 return (0);
5262
5263nla_put_failure:
5264 kfree_skb(skb);
5265 return -EINVAL;
5266}
5267
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305268static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305269 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305270 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305271 int data_len)
5272{
5273 u8 peer[6] = {0};
5274 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305275 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5276 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5277 eHalStatus status;
5278 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305279 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305280 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281
5282 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305283
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305284 if (!dev) {
5285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5286 return -EINVAL;
5287 }
5288
5289 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5290 if (!pAdapter) {
5291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5292 return -EINVAL;
5293 }
5294
Atul Mittal115287b2014-07-08 13:26:33 +05305295 status = wlan_hdd_validate_context(pHddCtx);
5296 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305298 return -EINVAL;
5299 }
5300 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305302 return -ENOTSUPP;
5303 }
5304 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5305 data, data_len,
5306 wlan_hdd_tdls_config_enable_policy)) {
5307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5308 return -EINVAL;
5309 }
5310
5311 /* Parse and fetch mac address */
5312 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5314 return -EINVAL;
5315 }
5316
5317 memcpy(peer, nla_data(
5318 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5319 sizeof(peer));
5320 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5321
5322 /* Parse and fetch channel */
5323 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5325 return -EINVAL;
5326 }
5327 pReqMsg.channel = nla_get_s32(
5328 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5330
5331 /* Parse and fetch global operating class */
5332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5334 return -EINVAL;
5335 }
5336 pReqMsg.global_operating_class = nla_get_s32(
5337 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5339 pReqMsg.global_operating_class);
5340
5341 /* Parse and fetch latency ms */
5342 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5344 return -EINVAL;
5345 }
5346 pReqMsg.max_latency_ms = nla_get_s32(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5349 pReqMsg.max_latency_ms);
5350
5351 /* Parse and fetch required bandwidth kbps */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5354 return -EINVAL;
5355 }
5356
5357 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5358 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5360 pReqMsg.min_bandwidth_kbps);
5361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305362 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305363 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305364 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305365 wlan_hdd_cfg80211_exttdls_callback);
5366
5367 EXIT();
5368 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305369}
5370
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305371static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5372 struct wireless_dev *wdev,
5373 const void *data,
5374 int data_len)
5375{
5376 int ret = 0;
5377
5378 vos_ssr_protect(__func__);
5379 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5380 vos_ssr_unprotect(__func__);
5381
5382 return ret;
5383}
5384
5385static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305386 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305387 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305388 int data_len)
5389{
5390 u8 peer[6] = {0};
5391 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5393 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5394 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305396 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305397
5398 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305399
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305400 if (!dev) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5402 return -EINVAL;
5403 }
5404
5405 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5406 if (!pAdapter) {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5408 return -EINVAL;
5409 }
5410
Atul Mittal115287b2014-07-08 13:26:33 +05305411 status = wlan_hdd_validate_context(pHddCtx);
5412 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305414 return -EINVAL;
5415 }
5416 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305418 return -ENOTSUPP;
5419 }
5420 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5421 data, data_len,
5422 wlan_hdd_tdls_config_disable_policy)) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5424 return -EINVAL;
5425 }
5426 /* Parse and fetch mac address */
5427 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5429 return -EINVAL;
5430 }
5431
5432 memcpy(peer, nla_data(
5433 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5434 sizeof(peer));
5435 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305437 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5438
5439 EXIT();
5440 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305441}
5442
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305443static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5444 struct wireless_dev *wdev,
5445 const void *data,
5446 int data_len)
5447{
5448 int ret = 0;
5449
5450 vos_ssr_protect(__func__);
5451 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5452 vos_ssr_unprotect(__func__);
5453
5454 return ret;
5455}
5456
Dasari Srinivas7875a302014-09-26 17:50:57 +05305457static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305458__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305459 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305460 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305461{
5462 struct net_device *dev = wdev->netdev;
5463 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5464 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5465 struct sk_buff *skb = NULL;
5466 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305467 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305469 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305470
5471 ret = wlan_hdd_validate_context(pHddCtx);
5472 if (0 != ret)
5473 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305474 return ret;
5475 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305476 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5477 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5478 fset |= WIFI_FEATURE_INFRA;
5479 }
5480
5481 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5482 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5483 fset |= WIFI_FEATURE_INFRA_5G;
5484 }
5485
5486#ifdef WLAN_FEATURE_P2P
5487 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5488 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5489 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5490 fset |= WIFI_FEATURE_P2P;
5491 }
5492#endif
5493
5494 /* Soft-AP is supported currently by default */
5495 fset |= WIFI_FEATURE_SOFT_AP;
5496
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305497 /* HOTSPOT is a supplicant feature, enable it by default */
5498 fset |= WIFI_FEATURE_HOTSPOT;
5499
Dasari Srinivas7875a302014-09-26 17:50:57 +05305500#ifdef WLAN_FEATURE_EXTSCAN
5501 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5502 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5503 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5504 fset |= WIFI_FEATURE_EXTSCAN;
5505 }
5506#endif
5507
Dasari Srinivas7875a302014-09-26 17:50:57 +05305508 if (sme_IsFeatureSupportedByFW(NAN)) {
5509 hddLog(LOG1, FL("NAN is supported by firmware"));
5510 fset |= WIFI_FEATURE_NAN;
5511 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305512
5513 /* D2D RTT is not supported currently by default */
5514 if (sme_IsFeatureSupportedByFW(RTT)) {
5515 hddLog(LOG1, FL("RTT is supported by firmware"));
5516 fset |= WIFI_FEATURE_D2AP_RTT;
5517 }
5518
5519#ifdef FEATURE_WLAN_BATCH_SCAN
5520 if (fset & WIFI_FEATURE_EXTSCAN) {
5521 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5522 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5523 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5524 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5525 fset |= WIFI_FEATURE_BATCH_SCAN;
5526 }
5527#endif
5528
5529#ifdef FEATURE_WLAN_SCAN_PNO
5530 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5531 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5532 hddLog(LOG1, FL("PNO is supported by firmware"));
5533 fset |= WIFI_FEATURE_PNO;
5534 }
5535#endif
5536
5537 /* STA+STA is supported currently by default */
5538 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5539
5540#ifdef FEATURE_WLAN_TDLS
5541 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5542 sme_IsFeatureSupportedByFW(TDLS)) {
5543 hddLog(LOG1, FL("TDLS is supported by firmware"));
5544 fset |= WIFI_FEATURE_TDLS;
5545 }
5546
5547 /* TDLS_OFFCHANNEL is not supported currently by default */
5548#endif
5549
5550#ifdef WLAN_AP_STA_CONCURRENCY
5551 /* AP+STA concurrency is supported currently by default */
5552 fset |= WIFI_FEATURE_AP_STA;
5553#endif
5554
Mukul Sharma5add0532015-08-17 15:57:47 +05305555#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5556 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5557 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5558#endif
5559
Dasari Srinivas7875a302014-09-26 17:50:57 +05305560 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5561 NLMSG_HDRLEN);
5562
5563 if (!skb) {
5564 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5565 return -EINVAL;
5566 }
5567 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5568
5569 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5570 hddLog(LOGE, FL("nla put fail"));
5571 goto nla_put_failure;
5572 }
5573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305574 ret = cfg80211_vendor_cmd_reply(skb);
5575 EXIT();
5576 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577
5578nla_put_failure:
5579 kfree_skb(skb);
5580 return -EINVAL;
5581}
5582
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305583static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305584wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5585 struct wireless_dev *wdev,
5586 const void *data, int data_len)
5587{
5588 int ret = 0;
5589
5590 vos_ssr_protect(__func__);
5591 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5592 vos_ssr_unprotect(__func__);
5593
5594 return ret;
5595}
5596
5597static int
5598__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305599 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305600 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305601{
5602 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5603 uint8_t i, feature_sets, max_feature_sets;
5604 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5605 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5607 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305608
5609 ENTER();
5610
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305611 ret = wlan_hdd_validate_context(pHddCtx);
5612 if (0 != ret)
5613 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305614 return ret;
5615 }
5616
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305617 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5618 data, data_len, NULL)) {
5619 hddLog(LOGE, FL("Invalid ATTR"));
5620 return -EINVAL;
5621 }
5622
5623 /* Parse and fetch max feature set */
5624 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5625 hddLog(LOGE, FL("Attr max feature set size failed"));
5626 return -EINVAL;
5627 }
5628 max_feature_sets = nla_get_u32(
5629 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5630 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5631
5632 /* Fill feature combination matrix */
5633 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305634 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5635 WIFI_FEATURE_P2P;
5636
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305637 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5638 WIFI_FEATURE_SOFT_AP;
5639
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305640 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5641 WIFI_FEATURE_SOFT_AP;
5642
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305643 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5644 WIFI_FEATURE_SOFT_AP |
5645 WIFI_FEATURE_P2P;
5646
5647 /* Add more feature combinations here */
5648
5649 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5650 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5651 hddLog(LOG1, "Feature set matrix");
5652 for (i = 0; i < feature_sets; i++)
5653 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5654
5655 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5656 sizeof(u32) * feature_sets +
5657 NLMSG_HDRLEN);
5658
5659 if (reply_skb) {
5660 if (nla_put_u32(reply_skb,
5661 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5662 feature_sets) ||
5663 nla_put(reply_skb,
5664 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5665 sizeof(u32) * feature_sets, feature_set_matrix)) {
5666 hddLog(LOGE, FL("nla put fail"));
5667 kfree_skb(reply_skb);
5668 return -EINVAL;
5669 }
5670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305671 ret = cfg80211_vendor_cmd_reply(reply_skb);
5672 EXIT();
5673 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305674 }
5675 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5676 return -ENOMEM;
5677
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305678}
5679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305680static int
5681wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5682 struct wireless_dev *wdev,
5683 const void *data, int data_len)
5684{
5685 int ret = 0;
5686
5687 vos_ssr_protect(__func__);
5688 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5689 data_len);
5690 vos_ssr_unprotect(__func__);
5691
5692 return ret;
5693}
5694
c_manjeecfd1efb2015-09-25 19:32:34 +05305695
5696static int
5697__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data, int data_len)
5700{
5701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5702 int ret;
5703 ENTER();
5704
5705 ret = wlan_hdd_validate_context(pHddCtx);
5706 if (0 != ret)
5707 {
5708 return ret;
5709 }
5710
5711 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5712 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5713 {
5714 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5715 return -EINVAL;
5716 }
5717 /*call common API for FW mem dump req*/
5718 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5719
5720 EXIT();
5721 return ret;
5722}
5723
5724/**
5725 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5726 * @wiphy: pointer to wireless wiphy structure.
5727 * @wdev: pointer to wireless_dev structure.
5728 * @data: Pointer to the NL data.
5729 * @data_len:Length of @data
5730 *
5731 * This is called when wlan driver needs to get the firmware memory dump
5732 * via vendor specific command.
5733 *
5734 * Return: 0 on success, error number otherwise.
5735 */
5736
5737static int
5738wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5739 struct wireless_dev *wdev,
5740 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305741{
5742 int ret = 0;
5743 vos_ssr_protect(__func__);
5744 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5745 data_len);
5746 vos_ssr_unprotect(__func__);
5747 return ret;
5748}
c_manjeecfd1efb2015-09-25 19:32:34 +05305749
Sushant Kaushik8e644982015-09-23 12:18:54 +05305750static const struct
5751nla_policy
5752qca_wlan_vendor_wifi_logger_start_policy
5753[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5754 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5755 = {.type = NLA_U32 },
5756 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5757 = {.type = NLA_U32 },
5758 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5759 = {.type = NLA_U32 },
5760};
5761
5762/**
5763 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5764 * or disable the collection of packet statistics from the firmware
5765 * @wiphy: WIPHY structure pointer
5766 * @wdev: Wireless device structure pointer
5767 * @data: Pointer to the data received
5768 * @data_len: Length of the data received
5769 *
5770 * This function is used to enable or disable the collection of packet
5771 * statistics from the firmware
5772 *
5773 * Return: 0 on success and errno on failure
5774 */
5775static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5776 struct wireless_dev *wdev,
5777 const void *data,
5778 int data_len)
5779{
5780 eHalStatus status;
5781 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5782 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5783 tAniWifiStartLog start_log;
5784
5785 status = wlan_hdd_validate_context(hdd_ctx);
5786 if (0 != status) {
5787 return -EINVAL;
5788 }
5789
5790 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5791 data, data_len,
5792 qca_wlan_vendor_wifi_logger_start_policy)) {
5793 hddLog(LOGE, FL("Invalid attribute"));
5794 return -EINVAL;
5795 }
5796
5797 /* Parse and fetch ring id */
5798 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5799 hddLog(LOGE, FL("attr ATTR failed"));
5800 return -EINVAL;
5801 }
5802 start_log.ringId = nla_get_u32(
5803 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5804 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5805
5806 /* Parse and fetch verbose level */
5807 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5808 hddLog(LOGE, FL("attr verbose_level failed"));
5809 return -EINVAL;
5810 }
5811 start_log.verboseLevel = nla_get_u32(
5812 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5813 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5814
5815 /* Parse and fetch flag */
5816 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5817 hddLog(LOGE, FL("attr flag failed"));
5818 return -EINVAL;
5819 }
5820 start_log.flag = nla_get_u32(
5821 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5822 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5823
5824 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305825 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5826 !vos_isPktStatsEnabled()))
5827
Sushant Kaushik8e644982015-09-23 12:18:54 +05305828 {
5829 hddLog(LOGE, FL("per pkt stats not enabled"));
5830 return -EINVAL;
5831 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305832
Sushant Kaushik33200572015-08-05 16:46:20 +05305833 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305834 return 0;
5835}
5836
5837/**
5838 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5839 * or disable the collection of packet statistics from the firmware
5840 * @wiphy: WIPHY structure pointer
5841 * @wdev: Wireless device structure pointer
5842 * @data: Pointer to the data received
5843 * @data_len: Length of the data received
5844 *
5845 * This function is used to enable or disable the collection of packet
5846 * statistics from the firmware
5847 *
5848 * Return: 0 on success and errno on failure
5849 */
5850static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5851 struct wireless_dev *wdev,
5852 const void *data,
5853 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305854{
5855 int ret = 0;
5856
5857 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305858
5859 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5860 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305861 vos_ssr_unprotect(__func__);
5862
5863 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305864}
5865
5866
Agarwal Ashish738843c2014-09-25 12:27:56 +05305867static const struct nla_policy
5868wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5869 +1] =
5870{
5871 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5872};
5873
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305874static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305875 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305876 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305877 int data_len)
5878{
5879 struct net_device *dev = wdev->netdev;
5880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5881 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5882 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5883 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5884 eHalStatus status;
5885 u32 dfsFlag = 0;
5886
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305887 ENTER();
5888
Agarwal Ashish738843c2014-09-25 12:27:56 +05305889 status = wlan_hdd_validate_context(pHddCtx);
5890 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305891 return -EINVAL;
5892 }
5893 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5894 data, data_len,
5895 wlan_hdd_set_no_dfs_flag_config_policy)) {
5896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5897 return -EINVAL;
5898 }
5899
5900 /* Parse and fetch required bandwidth kbps */
5901 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5903 return -EINVAL;
5904 }
5905
5906 dfsFlag = nla_get_u32(
5907 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5908 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5909 dfsFlag);
5910
5911 pHddCtx->disable_dfs_flag = dfsFlag;
5912
5913 sme_disable_dfs_channel(hHal, dfsFlag);
5914 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305915
5916 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305917 return 0;
5918}
Atul Mittal115287b2014-07-08 13:26:33 +05305919
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305920static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5921 struct wireless_dev *wdev,
5922 const void *data,
5923 int data_len)
5924{
5925 int ret = 0;
5926
5927 vos_ssr_protect(__func__);
5928 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5929 vos_ssr_unprotect(__func__);
5930
5931 return ret;
5932
5933}
5934
Mukul Sharma2a271632014-10-13 14:59:01 +05305935const struct
5936nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5937{
5938 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5939 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5940};
5941
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305942static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305943 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305944{
5945
5946 u8 bssid[6] = {0};
5947 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5948 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5949 eHalStatus status = eHAL_STATUS_SUCCESS;
5950 v_U32_t isFwrRoamEnabled = FALSE;
5951 int ret;
5952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305953 ENTER();
5954
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305955 ret = wlan_hdd_validate_context(pHddCtx);
5956 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305957 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305958 }
5959
5960 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5961 data, data_len,
5962 qca_wlan_vendor_attr);
5963 if (ret){
5964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5965 return -EINVAL;
5966 }
5967
5968 /* Parse and fetch Enable flag */
5969 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5971 return -EINVAL;
5972 }
5973
5974 isFwrRoamEnabled = nla_get_u32(
5975 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5976
5977 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5978
5979 /* Parse and fetch bssid */
5980 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5982 return -EINVAL;
5983 }
5984
5985 memcpy(bssid, nla_data(
5986 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5987 sizeof(bssid));
5988 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5989
5990 //Update roaming
5991 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305992 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305993 return status;
5994}
5995
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305996static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5997 struct wireless_dev *wdev, const void *data, int data_len)
5998{
5999 int ret = 0;
6000
6001 vos_ssr_protect(__func__);
6002 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6003 vos_ssr_unprotect(__func__);
6004
6005 return ret;
6006}
6007
Sushant Kaushik847890c2015-09-28 16:05:17 +05306008static const struct
6009nla_policy
6010qca_wlan_vendor_get_wifi_info_policy[
6011 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6012 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6013 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6014};
6015
6016
6017/**
6018 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6019 * @wiphy: pointer to wireless wiphy structure.
6020 * @wdev: pointer to wireless_dev structure.
6021 * @data: Pointer to the data to be passed via vendor interface
6022 * @data_len:Length of the data to be passed
6023 *
6024 * This is called when wlan driver needs to send wifi driver related info
6025 * (driver/fw version) to the user space application upon request.
6026 *
6027 * Return: Return the Success or Failure code.
6028 */
6029static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6030 struct wireless_dev *wdev,
6031 const void *data, int data_len)
6032{
6033 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6034 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6035 tSirVersionString version;
6036 uint32 version_len;
6037 uint8 attr;
6038 int status;
6039 struct sk_buff *reply_skb = NULL;
6040
6041 if (VOS_FTM_MODE == hdd_get_conparam()) {
6042 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6043 return -EINVAL;
6044 }
6045
6046 status = wlan_hdd_validate_context(hdd_ctx);
6047 if (0 != status) {
6048 hddLog(LOGE, FL("HDD context is not valid"));
6049 return -EINVAL;
6050 }
6051
6052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6053 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6054 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6055 return -EINVAL;
6056 }
6057
6058 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6059 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6060 QWLAN_VERSIONSTR);
6061 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6062 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6063 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6064 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6065 hdd_ctx->fw_Version);
6066 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6067 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6068 } else {
6069 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6070 return -EINVAL;
6071 }
6072
6073 version_len = strlen(version);
6074 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6075 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6076 if (!reply_skb) {
6077 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6078 return -ENOMEM;
6079 }
6080
6081 if (nla_put(reply_skb, attr, version_len, version)) {
6082 hddLog(LOGE, FL("nla put fail"));
6083 kfree_skb(reply_skb);
6084 return -EINVAL;
6085 }
6086
6087 return cfg80211_vendor_cmd_reply(reply_skb);
6088}
6089
6090/**
6091 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6092 * @wiphy: pointer to wireless wiphy structure.
6093 * @wdev: pointer to wireless_dev structure.
6094 * @data: Pointer to the data to be passed via vendor interface
6095 * @data_len:Length of the data to be passed
6096 * @data_len: Length of the data received
6097 *
6098 * This function is used to enable or disable the collection of packet
6099 * statistics from the firmware
6100 *
6101 * Return: 0 on success and errno on failure
6102 */
6103
6104static int
6105wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6106 struct wireless_dev *wdev,
6107 const void *data, int data_len)
6108
6109
6110{
6111 int ret = 0;
6112
6113 vos_ssr_protect(__func__);
6114 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6115 wdev, data, data_len);
6116 vos_ssr_unprotect(__func__);
6117
6118 return ret;
6119}
6120
6121
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306122/**
6123 * __wlan_hdd_cfg80211_setband() - set band
6124 * @wiphy: Pointer to wireless phy
6125 * @wdev: Pointer to wireless device
6126 * @data: Pointer to data
6127 * @data_len: Data length
6128 *
6129 * Return: 0 on success, negative errno on failure
6130 */
6131static int
6132__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6133 struct wireless_dev *wdev,
6134 const void *data,
6135 int data_len)
6136{
6137 struct net_device *dev = wdev->netdev;
6138 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6139 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6140 int ret;
6141 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6142 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6143
6144 ENTER();
6145
6146 ret = wlan_hdd_validate_context(hdd_ctx);
6147 if (0 != ret) {
6148 hddLog(LOGE, FL("HDD context is not valid"));
6149 return ret;
6150 }
6151
6152 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6153 policy)) {
6154 hddLog(LOGE, FL("Invalid ATTR"));
6155 return -EINVAL;
6156 }
6157
6158 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6159 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6160 return -EINVAL;
6161 }
6162
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306163 hdd_ctx->isSetBandByNL = TRUE;
6164 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306165 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306166 hdd_ctx->isSetBandByNL = FALSE;
6167
6168 EXIT();
6169 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306170}
6171
6172/**
6173 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6174 * @wiphy: wiphy structure pointer
6175 * @wdev: Wireless device structure pointer
6176 * @data: Pointer to the data received
6177 * @data_len: Length of @data
6178 *
6179 * Return: 0 on success; errno on failure
6180 */
6181static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6182 struct wireless_dev *wdev,
6183 const void *data,
6184 int data_len)
6185{
6186 int ret = 0;
6187
6188 vos_ssr_protect(__func__);
6189 ret = __wlan_hdd_cfg80211_setband(wiphy,
6190 wdev, data, data_len);
6191 vos_ssr_unprotect(__func__);
6192
6193 return ret;
6194}
6195
Sunil Duttc69bccb2014-05-26 21:30:20 +05306196const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
6197{
Mukul Sharma2a271632014-10-13 14:59:01 +05306198 {
6199 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6200 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
6201 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6202 WIPHY_VENDOR_CMD_NEED_NETDEV |
6203 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306204 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05306205 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306206
6207 {
6208 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6209 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
6210 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6211 WIPHY_VENDOR_CMD_NEED_NETDEV |
6212 WIPHY_VENDOR_CMD_NEED_RUNNING,
6213 .doit = wlan_hdd_cfg80211_nan_request
6214 },
6215
Sunil Duttc69bccb2014-05-26 21:30:20 +05306216#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6217 {
6218 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6219 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
6220 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6221 WIPHY_VENDOR_CMD_NEED_NETDEV |
6222 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306223 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05306224 },
6225
6226 {
6227 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6228 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6229 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6230 WIPHY_VENDOR_CMD_NEED_NETDEV |
6231 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306232 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306233 },
6234
6235 {
6236 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6237 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6238 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6239 WIPHY_VENDOR_CMD_NEED_NETDEV |
6240 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306241 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306242 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306243#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306244#ifdef WLAN_FEATURE_EXTSCAN
6245 {
6246 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6247 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6248 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6249 WIPHY_VENDOR_CMD_NEED_NETDEV |
6250 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306251 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306252 },
6253 {
6254 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6255 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6256 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6257 WIPHY_VENDOR_CMD_NEED_NETDEV |
6258 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306259 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306260 },
6261 {
6262 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6263 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6264 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6265 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306266 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306267 },
6268 {
6269 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6270 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6271 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6272 WIPHY_VENDOR_CMD_NEED_NETDEV |
6273 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306274 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306275 },
6276 {
6277 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6278 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6279 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6280 WIPHY_VENDOR_CMD_NEED_NETDEV |
6281 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306282 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306283 },
6284 {
6285 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6286 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6287 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6288 WIPHY_VENDOR_CMD_NEED_NETDEV |
6289 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306290 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306291 },
6292 {
6293 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6294 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6295 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6296 WIPHY_VENDOR_CMD_NEED_NETDEV |
6297 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306298 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306299 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306300 {
6301 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6302 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6303 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6304 WIPHY_VENDOR_CMD_NEED_NETDEV |
6305 WIPHY_VENDOR_CMD_NEED_RUNNING,
6306 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6307 },
6308 {
6309 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6310 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6311 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6312 WIPHY_VENDOR_CMD_NEED_NETDEV |
6313 WIPHY_VENDOR_CMD_NEED_RUNNING,
6314 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6315 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306316#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306317/*EXT TDLS*/
6318 {
6319 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6320 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6321 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6322 WIPHY_VENDOR_CMD_NEED_NETDEV |
6323 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306324 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306325 },
6326 {
6327 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6328 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6329 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6330 WIPHY_VENDOR_CMD_NEED_NETDEV |
6331 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306332 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306333 },
6334 {
6335 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6336 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6337 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6338 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306339 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306340 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306341 {
6342 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6343 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6344 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6345 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306346 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306347 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306348 {
6349 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6350 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6351 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6352 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306353 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306354 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306355 {
6356 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6357 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6358 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6359 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306360 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306361 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306362 {
6363 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6364 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6365 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6366 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306367 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306368 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306369 {
6370 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05306371 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
6372 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6373 WIPHY_VENDOR_CMD_NEED_NETDEV |
6374 WIPHY_VENDOR_CMD_NEED_RUNNING,
6375 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
6376 },
6377 {
6378 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306379 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6380 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6381 WIPHY_VENDOR_CMD_NEED_NETDEV |
6382 WIPHY_VENDOR_CMD_NEED_RUNNING,
6383 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05306384 },
6385 {
6386 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6387 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
6388 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6389 WIPHY_VENDOR_CMD_NEED_NETDEV,
6390 .doit = wlan_hdd_cfg80211_wifi_logger_start
6391 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05306392 {
6393 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6394 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6395 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6396 WIPHY_VENDOR_CMD_NEED_NETDEV|
6397 WIPHY_VENDOR_CMD_NEED_RUNNING,
6398 .doit = wlan_hdd_cfg80211_get_wifi_info
6399 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306400};
6401
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006402/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306403static const
6404struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006405{
6406#ifdef FEATURE_WLAN_CH_AVOID
6407 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306408 .vendor_id = QCA_NL80211_VENDOR_ID,
6409 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006410 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306411#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6412#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6413 {
6414 /* Index = 1*/
6415 .vendor_id = QCA_NL80211_VENDOR_ID,
6416 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6417 },
6418 {
6419 /* Index = 2*/
6420 .vendor_id = QCA_NL80211_VENDOR_ID,
6421 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6422 },
6423 {
6424 /* Index = 3*/
6425 .vendor_id = QCA_NL80211_VENDOR_ID,
6426 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6427 },
6428 {
6429 /* Index = 4*/
6430 .vendor_id = QCA_NL80211_VENDOR_ID,
6431 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6432 },
6433 {
6434 /* Index = 5*/
6435 .vendor_id = QCA_NL80211_VENDOR_ID,
6436 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6437 },
6438 {
6439 /* Index = 6*/
6440 .vendor_id = QCA_NL80211_VENDOR_ID,
6441 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6442 },
6443#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306444#ifdef WLAN_FEATURE_EXTSCAN
6445 {
6446 .vendor_id = QCA_NL80211_VENDOR_ID,
6447 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6448 },
6449 {
6450 .vendor_id = QCA_NL80211_VENDOR_ID,
6451 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6452 },
6453 {
6454 .vendor_id = QCA_NL80211_VENDOR_ID,
6455 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6456 },
6457 {
6458 .vendor_id = QCA_NL80211_VENDOR_ID,
6459 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6460 },
6461 {
6462 .vendor_id = QCA_NL80211_VENDOR_ID,
6463 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6464 },
6465 {
6466 .vendor_id = QCA_NL80211_VENDOR_ID,
6467 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6468 },
6469 {
6470 .vendor_id = QCA_NL80211_VENDOR_ID,
6471 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6472 },
6473 {
6474 .vendor_id = QCA_NL80211_VENDOR_ID,
6475 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6476 },
6477 {
6478 .vendor_id = QCA_NL80211_VENDOR_ID,
6479 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6480 },
6481 {
6482 .vendor_id = QCA_NL80211_VENDOR_ID,
6483 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6484 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306485 {
6486 .vendor_id = QCA_NL80211_VENDOR_ID,
6487 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6488 },
6489 {
6490 .vendor_id = QCA_NL80211_VENDOR_ID,
6491 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6492 },
6493 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6494 .vendor_id = QCA_NL80211_VENDOR_ID,
6495 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6496 },
6497 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6498 .vendor_id = QCA_NL80211_VENDOR_ID,
6499 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6500 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306501#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306502/*EXT TDLS*/
6503 {
6504 .vendor_id = QCA_NL80211_VENDOR_ID,
6505 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6506 },
c_manjeecfd1efb2015-09-25 19:32:34 +05306507 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
6508 .vendor_id = QCA_NL80211_VENDOR_ID,
6509 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
6510 },
6511
Srinivas Dasari030bad32015-02-18 23:23:54 +05306512
6513 {
6514 .vendor_id = QCA_NL80211_VENDOR_ID,
6515 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6516 },
6517
Sushant Kaushik084f6592015-09-10 13:11:56 +05306518 {
6519 .vendor_id = QCA_NL80211_VENDOR_ID,
6520 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6521 }
6522
6523
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006524};
6525
Jeff Johnson295189b2012-06-20 16:38:30 -07006526/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306527 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306528 * This function is called by hdd_wlan_startup()
6529 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306530 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306532struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006533{
6534 struct wiphy *wiphy;
6535 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306536 /*
6537 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 */
6539 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6540
6541 if (!wiphy)
6542 {
6543 /* Print error and jump into err label and free the memory */
6544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6545 return NULL;
6546 }
6547
Sunil Duttc69bccb2014-05-26 21:30:20 +05306548
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 return wiphy;
6550}
6551
6552/*
6553 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306554 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 * private ioctl to change the band value
6556 */
6557int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6558{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306559 int i, j;
6560 eNVChannelEnabledType channelEnabledState;
6561
Jeff Johnsone7245742012-09-05 17:12:55 -07006562 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306563
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306564 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306566
6567 if (NULL == wiphy->bands[i])
6568 {
6569 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6570 __func__, i);
6571 continue;
6572 }
6573
6574 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6575 {
6576 struct ieee80211_supported_band *band = wiphy->bands[i];
6577
6578 channelEnabledState = vos_nv_getChannelEnabledState(
6579 band->channels[j].hw_value);
6580
6581 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6582 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306583 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306584 continue;
6585 }
6586 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6587 {
6588 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6589 continue;
6590 }
6591
6592 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6593 NV_CHANNEL_INVALID == channelEnabledState)
6594 {
6595 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6596 }
6597 else if (NV_CHANNEL_DFS == channelEnabledState)
6598 {
6599 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6600 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6601 }
6602 else
6603 {
6604 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6605 |IEEE80211_CHAN_RADAR);
6606 }
6607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006608 }
6609 return 0;
6610}
6611/*
6612 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306613 * This function is called by hdd_wlan_startup()
6614 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 * This function is used to initialize and register wiphy structure.
6616 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306617int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 struct wiphy *wiphy,
6619 hdd_config_t *pCfg
6620 )
6621{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306622 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306623 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6624
Jeff Johnsone7245742012-09-05 17:12:55 -07006625 ENTER();
6626
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 /* Now bind the underlying wlan device with wiphy */
6628 set_wiphy_dev(wiphy, dev);
6629
6630 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006631
Kiet Lam6c583332013-10-14 05:37:09 +05306632#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006633 /* the flag for the other case would be initialzed in
6634 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006635 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306636#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006637
Amar Singhalfddc28c2013-09-05 13:03:40 -07006638 /* This will disable updating of NL channels from passive to
6639 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6641 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6642#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006643 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306644#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006645
Amar Singhala49cbc52013-10-08 18:37:44 -07006646
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006647#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006648 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6649 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6650 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006651 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306652#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6653 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6654#else
6655 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6656#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006657#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006658
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006659#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006660 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006661#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006662 || pCfg->isFastRoamIniFeatureEnabled
6663#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006664#ifdef FEATURE_WLAN_ESE
6665 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006666#endif
6667 )
6668 {
6669 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6670 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006671#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006672#ifdef FEATURE_WLAN_TDLS
6673 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6674 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6675#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306676#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306677 if (pCfg->configPNOScanSupport)
6678 {
6679 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6680 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6681 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6682 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6683 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306684#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006685
Abhishek Singh10d85972015-04-17 10:27:23 +05306686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6687 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6688#endif
6689
Amar Singhalfddc28c2013-09-05 13:03:40 -07006690#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006691 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6692 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006693 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006694 driver need to determine what to do with both
6695 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006696
6697 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006698#else
6699 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006700#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006701
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306702 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6703
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306704 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006705
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306706 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6707
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306709 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6710 | BIT(NL80211_IFTYPE_ADHOC)
6711 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6712 | BIT(NL80211_IFTYPE_P2P_GO)
6713 | BIT(NL80211_IFTYPE_AP);
6714
6715 if (VOS_MONITOR_MODE == hdd_get_conparam())
6716 {
6717 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6718 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006719
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306720 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006721 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6723 if( pCfg->enableMCC )
6724 {
6725 /* Currently, supports up to two channels */
6726 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006727
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306728 if( !pCfg->allowMCCGODiffBI )
6729 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006730
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306731 }
6732 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6733 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006734#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306735 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 /* Before registering we need to update the ht capabilitied based
6738 * on ini values*/
6739 if( !pCfg->ShortGI20MhzEnable )
6740 {
6741 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6742 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6743 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6744 }
6745
6746 if( !pCfg->ShortGI40MhzEnable )
6747 {
6748 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6749 }
6750
6751 if( !pCfg->nChannelBondingMode5GHz )
6752 {
6753 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6754 }
6755
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306756 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306757 if (true == hdd_is_5g_supported(pHddCtx))
6758 {
6759 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6760 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306761
6762 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6763 {
6764
6765 if (NULL == wiphy->bands[i])
6766 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306767 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306768 __func__, i);
6769 continue;
6770 }
6771
6772 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6773 {
6774 struct ieee80211_supported_band *band = wiphy->bands[i];
6775
6776 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6777 {
6778 // Enable social channels for P2P
6779 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6780 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6781 else
6782 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6783 continue;
6784 }
6785 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6786 {
6787 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6788 continue;
6789 }
6790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 }
6792 /*Initialise the supported cipher suite details*/
6793 wiphy->cipher_suites = hdd_cipher_suites;
6794 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6795
6796 /*signal strength in mBm (100*dBm) */
6797 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6798
6799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306800 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006802
Sunil Duttc69bccb2014-05-26 21:30:20 +05306803 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6804 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006805 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6806 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6807
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306808 EXIT();
6809 return 0;
6810}
6811
6812/* In this function we are registering wiphy. */
6813int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6814{
6815 ENTER();
6816 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 if (0 > wiphy_register(wiphy))
6818 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306819 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6821 return -EIO;
6822 }
6823
6824 EXIT();
6825 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306826}
Jeff Johnson295189b2012-06-20 16:38:30 -07006827
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306828/* In this function we are updating channel list when,
6829 regulatory domain is FCC and country code is US.
6830 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6831 As per FCC smart phone is not a indoor device.
6832 GO should not opeate on indoor channels */
6833void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6834{
6835 int j;
6836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6837 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6838 //Default counrtycode from NV at the time of wiphy initialization.
6839 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6840 &defaultCountryCode[0]))
6841 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006842 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306843 }
6844 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6845 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306846 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6847 {
6848 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6849 return;
6850 }
6851 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6852 {
6853 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6854 // Mark UNII -1 band channel as passive
6855 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6856 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6857 }
6858 }
6859}
6860
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306861/* This function registers for all frame which supplicant is interested in */
6862void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006863{
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6865 /* Register for all P2P action, public action etc frames */
6866 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6867
Jeff Johnsone7245742012-09-05 17:12:55 -07006868 ENTER();
6869
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 /* Right now we are registering these frame when driver is getting
6871 initialized. Once we will move to 2.6.37 kernel, in which we have
6872 frame register ops, we will move this code as a part of that */
6873 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306874 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6876
6877 /* GAS Initial Response */
6878 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6879 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306880
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 /* GAS Comeback Request */
6882 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6883 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6884
6885 /* GAS Comeback Response */
6886 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6887 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6888
6889 /* P2P Public Action */
6890 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306891 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 P2P_PUBLIC_ACTION_FRAME_SIZE );
6893
6894 /* P2P Action */
6895 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6896 (v_U8_t*)P2P_ACTION_FRAME,
6897 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006898
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306899 /* WNM BSS Transition Request frame */
6900 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6901 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6902 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006903
6904 /* WNM-Notification */
6905 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6906 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6907 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006908}
6909
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306910void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006911{
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6913 /* Register for all P2P action, public action etc frames */
6914 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6915
Jeff Johnsone7245742012-09-05 17:12:55 -07006916 ENTER();
6917
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 /* Right now we are registering these frame when driver is getting
6919 initialized. Once we will move to 2.6.37 kernel, in which we have
6920 frame register ops, we will move this code as a part of that */
6921 /* GAS Initial Request */
6922
6923 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6924 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6925
6926 /* GAS Initial Response */
6927 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6928 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306929
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 /* GAS Comeback Request */
6931 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6932 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6933
6934 /* GAS Comeback Response */
6935 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6936 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6937
6938 /* P2P Public Action */
6939 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306940 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 P2P_PUBLIC_ACTION_FRAME_SIZE );
6942
6943 /* P2P Action */
6944 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6945 (v_U8_t*)P2P_ACTION_FRAME,
6946 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006947 /* WNM-Notification */
6948 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6949 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6950 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006951}
6952
6953#ifdef FEATURE_WLAN_WAPI
6954void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306955 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006956{
6957 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6958 tCsrRoamSetKey setKey;
6959 v_BOOL_t isConnected = TRUE;
6960 int status = 0;
6961 v_U32_t roamId= 0xFF;
6962 tANI_U8 *pKeyPtr = NULL;
6963 int n = 0;
6964
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6966 __func__, hdd_device_modetoString(pAdapter->device_mode),
6967 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006968
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306969 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 setKey.keyId = key_index; // Store Key ID
6971 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6972 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6973 setKey.paeRole = 0 ; // the PAE role
6974 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6975 {
6976 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6977 }
6978 else
6979 {
6980 isConnected = hdd_connIsConnected(pHddStaCtx);
6981 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6982 }
6983 setKey.keyLength = key_Len;
6984 pKeyPtr = setKey.Key;
6985 memcpy( pKeyPtr, key, key_Len);
6986
Arif Hussain6d2a3322013-11-17 19:50:10 -08006987 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 __func__, key_Len);
6989 for (n = 0 ; n < key_Len; n++)
6990 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6991 __func__,n,setKey.Key[n]);
6992
6993 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6994 if ( isConnected )
6995 {
6996 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6997 pAdapter->sessionId, &setKey, &roamId );
6998 }
6999 if ( status != 0 )
7000 {
7001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7002 "[%4d] sme_RoamSetKey returned ERROR status= %d",
7003 __LINE__, status );
7004 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7005 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05307006 /* Need to clear any trace of key value in the memory.
7007 * Thus zero out the memory even though it is local
7008 * variable.
7009 */
7010 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07007011}
7012#endif /* FEATURE_WLAN_WAPI*/
7013
7014#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307015int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 beacon_data_t **ppBeacon,
7017 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007018#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307019int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007020 beacon_data_t **ppBeacon,
7021 struct cfg80211_beacon_data *params,
7022 int dtim_period)
7023#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307024{
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 int size;
7026 beacon_data_t *beacon = NULL;
7027 beacon_data_t *old = NULL;
7028 int head_len,tail_len;
7029
Jeff Johnsone7245742012-09-05 17:12:55 -07007030 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307032 {
7033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7034 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307036 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007037
7038 old = pAdapter->sessionCtx.ap.beacon;
7039
7040 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307041 {
7042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7043 FL("session(%d) old and new heads points to NULL"),
7044 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307046 }
7047
7048 if (params->tail && !params->tail_len)
7049 {
7050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7051 FL("tail_len is zero but tail is not NULL"));
7052 return -EINVAL;
7053 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007054
Jeff Johnson295189b2012-06-20 16:38:30 -07007055#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
7056 /* Kernel 3.0 is not updating dtim_period for set beacon */
7057 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307058 {
7059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7060 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007063#endif
7064
7065 if(params->head)
7066 head_len = params->head_len;
7067 else
7068 head_len = old->head_len;
7069
7070 if(params->tail || !old)
7071 tail_len = params->tail_len;
7072 else
7073 tail_len = old->tail_len;
7074
7075 size = sizeof(beacon_data_t) + head_len + tail_len;
7076
7077 beacon = kzalloc(size, GFP_KERNEL);
7078
7079 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307080 {
7081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7082 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007085
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007086#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 if(params->dtim_period || !old )
7088 beacon->dtim_period = params->dtim_period;
7089 else
7090 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007091#else
7092 if(dtim_period || !old )
7093 beacon->dtim_period = dtim_period;
7094 else
7095 beacon->dtim_period = old->dtim_period;
7096#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307097
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
7099 beacon->tail = beacon->head + head_len;
7100 beacon->head_len = head_len;
7101 beacon->tail_len = tail_len;
7102
7103 if(params->head) {
7104 memcpy (beacon->head,params->head,beacon->head_len);
7105 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307106 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 if(old)
7108 memcpy (beacon->head,old->head,beacon->head_len);
7109 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307110
Jeff Johnson295189b2012-06-20 16:38:30 -07007111 if(params->tail) {
7112 memcpy (beacon->tail,params->tail,beacon->tail_len);
7113 }
7114 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307115 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 memcpy (beacon->tail,old->tail,beacon->tail_len);
7117 }
7118
7119 *ppBeacon = beacon;
7120
7121 kfree(old);
7122
7123 return 0;
7124
7125}
Jeff Johnson295189b2012-06-20 16:38:30 -07007126
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307127v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
7128#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7129 const v_U8_t *pIes,
7130#else
7131 v_U8_t *pIes,
7132#endif
7133 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007134{
7135 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307136 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307138
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307140 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 elem_id = ptr[0];
7142 elem_len = ptr[1];
7143 left -= 2;
7144 if(elem_len > left)
7145 {
7146 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007147 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 eid,elem_len,left);
7149 return NULL;
7150 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307151 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 {
7153 return ptr;
7154 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307155
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 left -= elem_len;
7157 ptr += (elem_len + 2);
7158 }
7159 return NULL;
7160}
7161
Jeff Johnson295189b2012-06-20 16:38:30 -07007162/* Check if rate is 11g rate or not */
7163static int wlan_hdd_rate_is_11g(u8 rate)
7164{
Sanjay Devnani28322e22013-06-21 16:13:40 -07007165 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 u8 i;
7167 for (i = 0; i < 8; i++)
7168 {
7169 if(rate == gRateArray[i])
7170 return TRUE;
7171 }
7172 return FALSE;
7173}
7174
7175/* Check for 11g rate and set proper 11g only mode */
7176static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
7177 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
7178{
7179 u8 i, num_rates = pIe[0];
7180
7181 pIe += 1;
7182 for ( i = 0; i < num_rates; i++)
7183 {
7184 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
7185 {
7186 /* If rate set have 11g rate than change the mode to 11G */
7187 *pSapHw_mode = eSAP_DOT11_MODE_11g;
7188 if (pIe[i] & BASIC_RATE_MASK)
7189 {
7190 /* If we have 11g rate as basic rate, it means mode
7191 is 11g only mode.
7192 */
7193 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
7194 *pCheckRatesfor11g = FALSE;
7195 }
7196 }
7197 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
7198 {
7199 *require_ht = TRUE;
7200 }
7201 }
7202 return;
7203}
7204
7205static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
7206{
7207 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7208 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7209 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7210 u8 checkRatesfor11g = TRUE;
7211 u8 require_ht = FALSE;
7212 u8 *pIe=NULL;
7213
7214 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
7215
7216 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7217 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7218 if (pIe != NULL)
7219 {
7220 pIe += 1;
7221 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7222 &pConfig->SapHw_mode);
7223 }
7224
7225 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7226 WLAN_EID_EXT_SUPP_RATES);
7227 if (pIe != NULL)
7228 {
7229
7230 pIe += 1;
7231 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7232 &pConfig->SapHw_mode);
7233 }
7234
7235 if( pConfig->channel > 14 )
7236 {
7237 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
7238 }
7239
7240 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7241 WLAN_EID_HT_CAPABILITY);
7242
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307243 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007244 {
7245 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7246 if(require_ht)
7247 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7248 }
7249}
7250
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307251static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7252 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7253{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007254 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307255 v_U8_t *pIe = NULL;
7256 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7257
7258 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7259 pBeacon->tail, pBeacon->tail_len);
7260
7261 if (pIe)
7262 {
7263 ielen = pIe[1] + 2;
7264 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7265 {
7266 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7267 }
7268 else
7269 {
7270 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7271 return -EINVAL;
7272 }
7273 *total_ielen += ielen;
7274 }
7275 return 0;
7276}
7277
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007278static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7279 v_U8_t *genie, v_U8_t *total_ielen)
7280{
7281 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7282 int left = pBeacon->tail_len;
7283 v_U8_t *ptr = pBeacon->tail;
7284 v_U8_t elem_id, elem_len;
7285 v_U16_t ielen = 0;
7286
7287 if ( NULL == ptr || 0 == left )
7288 return;
7289
7290 while (left >= 2)
7291 {
7292 elem_id = ptr[0];
7293 elem_len = ptr[1];
7294 left -= 2;
7295 if (elem_len > left)
7296 {
7297 hddLog( VOS_TRACE_LEVEL_ERROR,
7298 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7299 elem_id, elem_len, left);
7300 return;
7301 }
7302 if (IE_EID_VENDOR == elem_id)
7303 {
7304 /* skipping the VSIE's which we don't want to include or
7305 * it will be included by existing code
7306 */
7307 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7308#ifdef WLAN_FEATURE_WFD
7309 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7310#endif
7311 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7312 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7313 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7314 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7315 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7316 {
7317 ielen = ptr[1] + 2;
7318 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7319 {
7320 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7321 *total_ielen += ielen;
7322 }
7323 else
7324 {
7325 hddLog( VOS_TRACE_LEVEL_ERROR,
7326 "IE Length is too big "
7327 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7328 elem_id, elem_len, *total_ielen);
7329 }
7330 }
7331 }
7332
7333 left -= elem_len;
7334 ptr += (elem_len + 2);
7335 }
7336 return;
7337}
7338
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007339#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007340static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7341 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007342#else
7343static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7344 struct cfg80211_beacon_data *params)
7345#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007346{
7347 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307348 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007349 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007350 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007351
7352 genie = vos_mem_malloc(MAX_GENIE_LEN);
7353
7354 if(genie == NULL) {
7355
7356 return -ENOMEM;
7357 }
7358
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307359 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7360 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007361 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307362 hddLog(LOGE,
7363 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307364 ret = -EINVAL;
7365 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 }
7367
7368#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307369 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7370 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7371 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307372 hddLog(LOGE,
7373 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307374 ret = -EINVAL;
7375 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 }
7377#endif
7378
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307379 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7380 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307382 hddLog(LOGE,
7383 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307384 ret = -EINVAL;
7385 goto done;
7386 }
7387
7388 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7389 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007390 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007392
7393 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7394 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7395 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7396 {
7397 hddLog(LOGE,
7398 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007399 ret = -EINVAL;
7400 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007401 }
7402
7403 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7404 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7405 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7406 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7407 ==eHAL_STATUS_FAILURE)
7408 {
7409 hddLog(LOGE,
7410 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007411 ret = -EINVAL;
7412 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 }
7414
7415 // Added for ProResp IE
7416 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7417 {
7418 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7419 u8 probe_rsp_ie_len[3] = {0};
7420 u8 counter = 0;
7421 /* Check Probe Resp Length if it is greater then 255 then Store
7422 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7423 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7424 Store More then 255 bytes into One Variable.
7425 */
7426 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7427 {
7428 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7429 {
7430 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7431 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7432 }
7433 else
7434 {
7435 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7436 rem_probe_resp_ie_len = 0;
7437 }
7438 }
7439
7440 rem_probe_resp_ie_len = 0;
7441
7442 if (probe_rsp_ie_len[0] > 0)
7443 {
7444 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7445 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7446 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7447 probe_rsp_ie_len[0], NULL,
7448 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7449 {
7450 hddLog(LOGE,
7451 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007452 ret = -EINVAL;
7453 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 }
7455 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7456 }
7457
7458 if (probe_rsp_ie_len[1] > 0)
7459 {
7460 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7461 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7462 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7463 probe_rsp_ie_len[1], NULL,
7464 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7465 {
7466 hddLog(LOGE,
7467 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007468 ret = -EINVAL;
7469 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007470 }
7471 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7472 }
7473
7474 if (probe_rsp_ie_len[2] > 0)
7475 {
7476 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7477 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7478 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7479 probe_rsp_ie_len[2], NULL,
7480 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7481 {
7482 hddLog(LOGE,
7483 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007484 ret = -EINVAL;
7485 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 }
7487 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7488 }
7489
7490 if (probe_rsp_ie_len[1] == 0 )
7491 {
7492 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7493 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7494 eANI_BOOLEAN_FALSE) )
7495 {
7496 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007497 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007498 }
7499 }
7500
7501 if (probe_rsp_ie_len[2] == 0 )
7502 {
7503 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7504 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7505 eANI_BOOLEAN_FALSE) )
7506 {
7507 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007508 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007509 }
7510 }
7511
7512 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7513 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7514 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7515 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7516 == eHAL_STATUS_FAILURE)
7517 {
7518 hddLog(LOGE,
7519 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007520 ret = -EINVAL;
7521 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 }
7523 }
7524 else
7525 {
7526 // Reset WNI_CFG_PROBE_RSP Flags
7527 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7528
7529 hddLog(VOS_TRACE_LEVEL_INFO,
7530 "%s: No Probe Response IE received in set beacon",
7531 __func__);
7532 }
7533
7534 // Added for AssocResp IE
7535 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7536 {
7537 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7538 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7539 params->assocresp_ies_len, NULL,
7540 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7541 {
7542 hddLog(LOGE,
7543 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007544 ret = -EINVAL;
7545 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 }
7547
7548 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7549 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7550 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7551 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7552 == eHAL_STATUS_FAILURE)
7553 {
7554 hddLog(LOGE,
7555 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007556 ret = -EINVAL;
7557 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007558 }
7559 }
7560 else
7561 {
7562 hddLog(VOS_TRACE_LEVEL_INFO,
7563 "%s: No Assoc Response IE received in set beacon",
7564 __func__);
7565
7566 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7567 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7568 eANI_BOOLEAN_FALSE) )
7569 {
7570 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007571 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007572 }
7573 }
7574
Jeff Johnsone7245742012-09-05 17:12:55 -07007575done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307577 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007578}
Jeff Johnson295189b2012-06-20 16:38:30 -07007579
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307580/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 * FUNCTION: wlan_hdd_validate_operation_channel
7582 * called by wlan_hdd_cfg80211_start_bss() and
7583 * wlan_hdd_cfg80211_set_channel()
7584 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307585 * channel list.
7586 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007587VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007588{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307589
Jeff Johnson295189b2012-06-20 16:38:30 -07007590 v_U32_t num_ch = 0;
7591 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7592 u32 indx = 0;
7593 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307594 v_U8_t fValidChannel = FALSE, count = 0;
7595 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307596
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7598
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307599 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307601 /* Validate the channel */
7602 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307604 if ( channel == rfChannels[count].channelNum )
7605 {
7606 fValidChannel = TRUE;
7607 break;
7608 }
7609 }
7610 if (fValidChannel != TRUE)
7611 {
7612 hddLog(VOS_TRACE_LEVEL_ERROR,
7613 "%s: Invalid Channel [%d]", __func__, channel);
7614 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 }
7616 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307617 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307619 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7620 valid_ch, &num_ch))
7621 {
7622 hddLog(VOS_TRACE_LEVEL_ERROR,
7623 "%s: failed to get valid channel list", __func__);
7624 return VOS_STATUS_E_FAILURE;
7625 }
7626 for (indx = 0; indx < num_ch; indx++)
7627 {
7628 if (channel == valid_ch[indx])
7629 {
7630 break;
7631 }
7632 }
7633
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307634 if (indx >= num_ch)
7635 {
7636 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7637 {
7638 eCsrBand band;
7639 unsigned int freq;
7640
7641 sme_GetFreqBand(hHal, &band);
7642
7643 if (eCSR_BAND_5G == band)
7644 {
7645#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7646 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7647 {
7648 freq = ieee80211_channel_to_frequency(channel,
7649 IEEE80211_BAND_2GHZ);
7650 }
7651 else
7652 {
7653 freq = ieee80211_channel_to_frequency(channel,
7654 IEEE80211_BAND_5GHZ);
7655 }
7656#else
7657 freq = ieee80211_channel_to_frequency(channel);
7658#endif
7659 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7660 return VOS_STATUS_SUCCESS;
7661 }
7662 }
7663
7664 hddLog(VOS_TRACE_LEVEL_ERROR,
7665 "%s: Invalid Channel [%d]", __func__, channel);
7666 return VOS_STATUS_E_FAILURE;
7667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307669
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672}
7673
Viral Modi3a32cc52013-02-08 11:14:52 -08007674/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307675 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007676 * This function is used to set the channel number
7677 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307678static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007679 struct ieee80211_channel *chan,
7680 enum nl80211_channel_type channel_type
7681 )
7682{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307683 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007684 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007685 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007686 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307687 hdd_context_t *pHddCtx;
7688 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007689
7690 ENTER();
7691
7692 if( NULL == dev )
7693 {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007695 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007696 return -ENODEV;
7697 }
7698 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307699
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7701 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7702 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007703 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307704 "%s: device_mode = %s (%d) freq = %d", __func__,
7705 hdd_device_modetoString(pAdapter->device_mode),
7706 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307707
7708 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7709 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307710 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007711 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307712 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007713 }
7714
7715 /*
7716 * Do freq to chan conversion
7717 * TODO: for 11a
7718 */
7719
7720 channel = ieee80211_frequency_to_channel(freq);
7721
7722 /* Check freq range */
7723 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7724 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7725 {
7726 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007727 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007728 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7729 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7730 return -EINVAL;
7731 }
7732
7733 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7734
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307735 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7736 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007737 {
7738 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7739 {
7740 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007741 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007742 return -EINVAL;
7743 }
7744 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7745 "%s: set channel to [%d] for device mode =%d",
7746 __func__, channel,pAdapter->device_mode);
7747 }
7748 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007749 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007750 )
7751 {
7752 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7753 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7754 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7755
7756 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7757 {
7758 /* Link is up then return cant set channel*/
7759 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007760 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007761 return -EINVAL;
7762 }
7763
7764 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7765 pHddStaCtx->conn_info.operationChannel = channel;
7766 pRoamProfile->ChannelInfo.ChannelList =
7767 &pHddStaCtx->conn_info.operationChannel;
7768 }
7769 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007770 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007771 )
7772 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307773 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7774 {
7775 if(VOS_STATUS_SUCCESS !=
7776 wlan_hdd_validate_operation_channel(pAdapter,channel))
7777 {
7778 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007779 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307780 return -EINVAL;
7781 }
7782 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7783 }
7784 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007785 {
7786 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7787
7788 /* If auto channel selection is configured as enable/ 1 then ignore
7789 channel set by supplicant
7790 */
7791 if ( cfg_param->apAutoChannelSelection )
7792 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307793 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7794 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007795 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307796 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7797 __func__, hdd_device_modetoString(pAdapter->device_mode),
7798 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007799 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307800 else
7801 {
7802 if(VOS_STATUS_SUCCESS !=
7803 wlan_hdd_validate_operation_channel(pAdapter,channel))
7804 {
7805 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007806 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307807 return -EINVAL;
7808 }
7809 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7810 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007811 }
7812 }
7813 else
7814 {
7815 hddLog(VOS_TRACE_LEVEL_FATAL,
7816 "%s: Invalid device mode failed to set valid channel", __func__);
7817 return -EINVAL;
7818 }
7819 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307820 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007821}
7822
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307823static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7824 struct net_device *dev,
7825 struct ieee80211_channel *chan,
7826 enum nl80211_channel_type channel_type
7827 )
7828{
7829 int ret;
7830
7831 vos_ssr_protect(__func__);
7832 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7833 vos_ssr_unprotect(__func__);
7834
7835 return ret;
7836}
7837
Jeff Johnson295189b2012-06-20 16:38:30 -07007838#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7839static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7840 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007841#else
7842static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7843 struct cfg80211_beacon_data *params,
7844 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307845 enum nl80211_hidden_ssid hidden_ssid,
7846 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007847#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007848{
7849 tsap_Config_t *pConfig;
7850 beacon_data_t *pBeacon = NULL;
7851 struct ieee80211_mgmt *pMgmt_frame;
7852 v_U8_t *pIe=NULL;
7853 v_U16_t capab_info;
7854 eCsrAuthType RSNAuthType;
7855 eCsrEncryptionType RSNEncryptType;
7856 eCsrEncryptionType mcRSNEncryptType;
7857 int status = VOS_STATUS_SUCCESS;
7858 tpWLAN_SAPEventCB pSapEventCallback;
7859 hdd_hostapd_state_t *pHostapdState;
7860 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7861 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307862 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307864 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007866 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307867 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007868 v_BOOL_t MFPCapable = VOS_FALSE;
7869 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307870 v_BOOL_t sapEnable11AC =
7871 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 ENTER();
7873
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307874 iniConfig = pHddCtx->cfg_ini;
7875
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7877
7878 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7879
7880 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7881
7882 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7883
7884 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7885
7886 //channel is already set in the set_channel Call back
7887 //pConfig->channel = pCommitConfig->channel;
7888
7889 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307890 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7892
7893 pConfig->dtim_period = pBeacon->dtim_period;
7894
Arif Hussain6d2a3322013-11-17 19:50:10 -08007895 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 pConfig->dtim_period);
7897
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007898 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007899 {
7900 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307902 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7903 {
7904 tANI_BOOLEAN restartNeeded;
7905 pConfig->ieee80211d = 1;
7906 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7907 sme_setRegInfo(hHal, pConfig->countryCode);
7908 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7909 }
7910 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007911 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007912 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007913 pConfig->ieee80211d = 1;
7914 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7915 sme_setRegInfo(hHal, pConfig->countryCode);
7916 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007918 else
7919 {
7920 pConfig->ieee80211d = 0;
7921 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307922 /*
7923 * If auto channel is configured i.e. channel is 0,
7924 * so skip channel validation.
7925 */
7926 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7927 {
7928 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7929 {
7930 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007931 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307932 return -EINVAL;
7933 }
7934 }
7935 else
7936 {
7937 if(1 != pHddCtx->is_dynamic_channel_range_set)
7938 {
7939 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7940 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7941 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7942 }
7943 pHddCtx->is_dynamic_channel_range_set = 0;
7944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007946 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 {
7948 pConfig->ieee80211d = 0;
7949 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307950
7951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7952 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7953 pConfig->authType = eSAP_OPEN_SYSTEM;
7954 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7955 pConfig->authType = eSAP_SHARED_KEY;
7956 else
7957 pConfig->authType = eSAP_AUTO_SWITCH;
7958#else
7959 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7960 pConfig->authType = eSAP_OPEN_SYSTEM;
7961 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7962 pConfig->authType = eSAP_SHARED_KEY;
7963 else
7964 pConfig->authType = eSAP_AUTO_SWITCH;
7965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007966
7967 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307968
7969 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7971
7972 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7973
7974 /*Set wps station to configured*/
7975 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7976
7977 if(pIe)
7978 {
7979 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7980 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007981 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 return -EINVAL;
7983 }
7984 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7985 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007986 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 /* Check 15 bit of WPS IE as it contain information for wps state
7988 * WPS state
7989 */
7990 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7991 {
7992 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7993 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7994 {
7995 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7996 }
7997 }
7998 }
7999 else
8000 {
8001 pConfig->wps_state = SAP_WPS_DISABLED;
8002 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308003 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07008004
c_hpothufe599e92014-06-16 11:38:55 +05308005 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
8006 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
8007 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
8008 eCSR_ENCRYPT_TYPE_NONE;
8009
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 pConfig->RSNWPAReqIELength = 0;
8011 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308012 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 WLAN_EID_RSN);
8014 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308015 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 pConfig->RSNWPAReqIELength = pIe[1] + 2;
8017 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
8018 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308019 /* The actual processing may eventually be more extensive than
8020 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07008021 * by the app.
8022 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308023 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
8025 &RSNEncryptType,
8026 &mcRSNEncryptType,
8027 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08008028 &MFPCapable,
8029 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07008030 pConfig->pRSNWPAReqIE[1]+2,
8031 pConfig->pRSNWPAReqIE );
8032
8033 if( VOS_STATUS_SUCCESS == status )
8034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308035 /* Now copy over all the security attributes you have
8036 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 * */
8038 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
8039 pConfig->mcRSNEncryptType = mcRSNEncryptType;
8040 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
8041 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308042 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008043 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
8045 }
8046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308047
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8049 pBeacon->tail, pBeacon->tail_len);
8050
8051 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
8052 {
8053 if (pConfig->pRSNWPAReqIE)
8054 {
8055 /*Mixed mode WPA/WPA2*/
8056 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
8057 pConfig->RSNWPAReqIELength += pIe[1] + 2;
8058 }
8059 else
8060 {
8061 pConfig->RSNWPAReqIELength = pIe[1] + 2;
8062 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
8063 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308064 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
8066 &RSNEncryptType,
8067 &mcRSNEncryptType,
8068 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08008069 &MFPCapable,
8070 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 pConfig->pRSNWPAReqIE[1]+2,
8072 pConfig->pRSNWPAReqIE );
8073
8074 if( VOS_STATUS_SUCCESS == status )
8075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308076 /* Now copy over all the security attributes you have
8077 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 * */
8079 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
8080 pConfig->mcRSNEncryptType = mcRSNEncryptType;
8081 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
8082 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308083 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008084 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
8086 }
8087 }
8088 }
8089
Jeff Johnson4416a782013-03-25 14:17:50 -07008090 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
8091 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
8092 return -EINVAL;
8093 }
8094
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
8096
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008097#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 if (params->ssid != NULL)
8099 {
8100 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
8101 pConfig->SSIDinfo.ssid.length = params->ssid_len;
8102 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
8103 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
8104 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008105#else
8106 if (ssid != NULL)
8107 {
8108 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
8109 pConfig->SSIDinfo.ssid.length = ssid_len;
8110 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
8111 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
8112 }
8113#endif
8114
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308115 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308117
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 /* default value */
8119 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
8120 pConfig->num_accept_mac = 0;
8121 pConfig->num_deny_mac = 0;
8122
8123 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8124 pBeacon->tail, pBeacon->tail_len);
8125
8126 /* pIe for black list is following form:
8127 type : 1 byte
8128 length : 1 byte
8129 OUI : 4 bytes
8130 acl type : 1 byte
8131 no of mac addr in black list: 1 byte
8132 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308133 */
8134 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 {
8136 pConfig->SapMacaddr_acl = pIe[6];
8137 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008138 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008139 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308140 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
8141 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8143 for (i = 0; i < pConfig->num_deny_mac; i++)
8144 {
8145 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8146 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 }
8149 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8150 pBeacon->tail, pBeacon->tail_len);
8151
8152 /* pIe for white list is following form:
8153 type : 1 byte
8154 length : 1 byte
8155 OUI : 4 bytes
8156 acl type : 1 byte
8157 no of mac addr in white list: 1 byte
8158 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159 */
8160 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 {
8162 pConfig->SapMacaddr_acl = pIe[6];
8163 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008164 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308166 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
8167 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8169 for (i = 0; i < pConfig->num_accept_mac; i++)
8170 {
8171 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8172 acl_entry++;
8173 }
8174 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308175
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 wlan_hdd_set_sapHwmode(pHostapdAdapter);
8177
Jeff Johnsone7245742012-09-05 17:12:55 -07008178#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008179 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308180 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
8181 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05308182 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
8183 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008184 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
8185 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308186 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
8187 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07008188 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308189 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07008190 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308191 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008192
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308193 /* If ACS disable and selected channel <= 14
8194 * OR
8195 * ACS enabled and ACS operating band is choosen as 2.4
8196 * AND
8197 * VHT in 2.4G Disabled
8198 * THEN
8199 * Fallback to 11N mode
8200 */
8201 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
8202 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05308203 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308204 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008205 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308206 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
8207 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008208 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
8209 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008210 }
8211#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 // ht_capab is not what the name conveys,this is used for protection bitmap
8214 pConfig->ht_capab =
8215 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
8216
8217 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
8218 {
8219 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
8220 return -EINVAL;
8221 }
8222
8223 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308224 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
8226 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308227 pConfig->obssProtEnabled =
8228 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07008229
Chet Lanctot8cecea22014-02-11 19:09:36 -08008230#ifdef WLAN_FEATURE_11W
8231 pConfig->mfpCapable = MFPCapable;
8232 pConfig->mfpRequired = MFPRequired;
8233 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
8234 pConfig->mfpCapable, pConfig->mfpRequired);
8235#endif
8236
Arif Hussain6d2a3322013-11-17 19:50:10 -08008237 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008239 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
8240 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8241 (int)pConfig->channel);
8242 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8243 pConfig->SapHw_mode, pConfig->privacy,
8244 pConfig->authType);
8245 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8246 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8247 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8248 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008249
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308250 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 {
8252 //Bss already started. just return.
8253 //TODO Probably it should update some beacon params.
8254 hddLog( LOGE, "Bss Already started...Ignore the request");
8255 EXIT();
8256 return 0;
8257 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308258
Agarwal Ashish51325b52014-06-16 16:50:49 +05308259 if (vos_max_concurrent_connections_reached()) {
8260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8261 return -EINVAL;
8262 }
8263
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 pConfig->persona = pHostapdAdapter->device_mode;
8265
Peng Xu2446a892014-09-05 17:21:18 +05308266 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8267 if ( NULL != psmeConfig)
8268 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308269 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308270 sme_GetConfigParam(hHal, psmeConfig);
8271 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308272#ifdef WLAN_FEATURE_AP_HT40_24G
8273 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8274 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8275 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8276 {
8277 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8278 sme_UpdateConfig (hHal, psmeConfig);
8279 }
8280#endif
Peng Xu2446a892014-09-05 17:21:18 +05308281 vos_mem_free(psmeConfig);
8282 }
Peng Xuafc34e32014-09-25 13:23:55 +05308283 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308284
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 pSapEventCallback = hdd_hostapd_SAPEventCB;
8286 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8287 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8288 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008289 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 return -EINVAL;
8291 }
8292
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308293 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008294 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8295
8296 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308297
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308299 {
8300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008301 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008302 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 VOS_ASSERT(0);
8304 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308305
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308307 /* Initialize WMM configuation */
8308 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308309 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008310
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008311#ifdef WLAN_FEATURE_P2P_DEBUG
8312 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8313 {
8314 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8315 {
8316 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8317 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008318 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008319 }
8320 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8321 {
8322 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8323 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008324 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008325 }
8326 }
8327#endif
8328
Jeff Johnson295189b2012-06-20 16:38:30 -07008329 pHostapdState->bCommit = TRUE;
8330 EXIT();
8331
8332 return 0;
8333}
8334
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008335#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308336static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308337 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 struct beacon_parameters *params)
8339{
8340 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308341 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308342 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008343
8344 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308345
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308346 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8347 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8348 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308349 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8350 hdd_device_modetoString(pAdapter->device_mode),
8351 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008352
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8354 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308355 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008356 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308357 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008358 }
8359
Agarwal Ashish51325b52014-06-16 16:50:49 +05308360 if (vos_max_concurrent_connections_reached()) {
8361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8362 return -EINVAL;
8363 }
8364
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308365 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 )
8368 {
8369 beacon_data_t *old,*new;
8370
8371 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308372
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 {
8375 hddLog(VOS_TRACE_LEVEL_WARN,
8376 FL("already beacon info added to session(%d)"),
8377 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008378 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308379 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008380
8381 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8382
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308383 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 {
8385 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008386 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 return -EINVAL;
8388 }
8389
8390 pAdapter->sessionCtx.ap.beacon = new;
8391
8392 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8393 }
8394
8395 EXIT();
8396 return status;
8397}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308398
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308399static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8400 struct net_device *dev,
8401 struct beacon_parameters *params)
8402{
8403 int ret;
8404
8405 vos_ssr_protect(__func__);
8406 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8407 vos_ssr_unprotect(__func__);
8408
8409 return ret;
8410}
8411
8412static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008413 struct net_device *dev,
8414 struct beacon_parameters *params)
8415{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308417 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8418 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308419 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008420
8421 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308422
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308423 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8424 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8425 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8427 __func__, hdd_device_modetoString(pAdapter->device_mode),
8428 pAdapter->device_mode);
8429
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308430 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8431 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308432 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008433 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308434 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008435 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308436
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308437 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308439 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 {
8441 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308444
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308446 {
8447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8448 FL("session(%d) old and new heads points to NULL"),
8449 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008452
8453 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8454
8455 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308456 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008457 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 return -EINVAL;
8459 }
8460
8461 pAdapter->sessionCtx.ap.beacon = new;
8462
8463 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8464 }
8465
8466 EXIT();
8467 return status;
8468}
8469
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308470static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8471 struct net_device *dev,
8472 struct beacon_parameters *params)
8473{
8474 int ret;
8475
8476 vos_ssr_protect(__func__);
8477 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8478 vos_ssr_unprotect(__func__);
8479
8480 return ret;
8481}
8482
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008483#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8484
8485#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308486static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008488#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308489static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008490 struct net_device *dev)
8491#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008492{
8493 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008494 hdd_context_t *pHddCtx = NULL;
8495 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308496 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308497 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008498
8499 ENTER();
8500
8501 if (NULL == pAdapter)
8502 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008504 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 return -ENODEV;
8506 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008507
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308508 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8509 TRACE_CODE_HDD_CFG80211_STOP_AP,
8510 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308511 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8512 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308513 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008514 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308515 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008516 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008517
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008518 pScanInfo = &pHddCtx->scan_info;
8519
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8521 __func__, hdd_device_modetoString(pAdapter->device_mode),
8522 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008523
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308524 ret = wlan_hdd_scan_abort(pAdapter);
8525
Girish Gowli4bf7a632014-06-12 13:42:11 +05308526 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008527 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8529 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308530
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308531 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008532 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8534 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008535
Jeff Johnsone7245742012-09-05 17:12:55 -07008536 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308537 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008538 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308539 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008540 }
8541
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308542 /* Delete all associated STAs before stopping AP/P2P GO */
8543 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308544 hdd_hostapd_stop(dev);
8545
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 )
8549 {
8550 beacon_data_t *old;
8551
8552 old = pAdapter->sessionCtx.ap.beacon;
8553
8554 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308555 {
8556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8557 FL("session(%d) beacon data points to NULL"),
8558 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308560 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008561
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008563
8564 mutex_lock(&pHddCtx->sap_lock);
8565 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8566 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008567 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 {
8569 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8570
8571 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8572
8573 if (!VOS_IS_STATUS_SUCCESS(status))
8574 {
8575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008576 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308578 }
8579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308581 /* BSS stopped, clear the active sessions for this device mode */
8582 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 }
8584 mutex_unlock(&pHddCtx->sap_lock);
8585
8586 if(status != VOS_STATUS_SUCCESS)
8587 {
8588 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008589 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 return -EINVAL;
8591 }
8592
Jeff Johnson4416a782013-03-25 14:17:50 -07008593 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8595 ==eHAL_STATUS_FAILURE)
8596 {
8597 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008598 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 }
8600
Jeff Johnson4416a782013-03-25 14:17:50 -07008601 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8603 eANI_BOOLEAN_FALSE) )
8604 {
8605 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008606 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 }
8608
8609 // Reset WNI_CFG_PROBE_RSP Flags
8610 wlan_hdd_reset_prob_rspies(pAdapter);
8611
8612 pAdapter->sessionCtx.ap.beacon = NULL;
8613 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008614#ifdef WLAN_FEATURE_P2P_DEBUG
8615 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8616 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8617 {
8618 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8619 "GO got removed");
8620 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8621 }
8622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008623 }
8624 EXIT();
8625 return status;
8626}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008627
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308628#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8629static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8630 struct net_device *dev)
8631{
8632 int ret;
8633
8634 vos_ssr_protect(__func__);
8635 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8636 vos_ssr_unprotect(__func__);
8637
8638 return ret;
8639}
8640#else
8641static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8642 struct net_device *dev)
8643{
8644 int ret;
8645
8646 vos_ssr_protect(__func__);
8647 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8648 vos_ssr_unprotect(__func__);
8649
8650 return ret;
8651}
8652#endif
8653
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008654#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8655
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308656static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308657 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008658 struct cfg80211_ap_settings *params)
8659{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308660 hdd_adapter_t *pAdapter;
8661 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308662 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008663
8664 ENTER();
8665
Girish Gowlib143d7a2015-02-18 19:39:55 +05308666 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008667 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308669 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308670 return -ENODEV;
8671 }
8672
8673 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8674 if (NULL == pAdapter)
8675 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308677 "%s: HDD adapter is Null", __func__);
8678 return -ENODEV;
8679 }
8680
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308681 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8682 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8683 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308684 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8685 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308687 "%s: HDD adapter magic is invalid", __func__);
8688 return -ENODEV;
8689 }
8690
8691 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308692 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308693 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308694 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308695 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308696 }
8697
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308698 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8699 __func__, hdd_device_modetoString(pAdapter->device_mode),
8700 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308701
8702 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008703 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008704 )
8705 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308706 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008707
8708 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308709
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008710 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308711 {
8712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8713 FL("already beacon info added to session(%d)"),
8714 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008715 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308716 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008717
Girish Gowlib143d7a2015-02-18 19:39:55 +05308718#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8719 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8720 &new,
8721 &params->beacon);
8722#else
8723 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8724 &new,
8725 &params->beacon,
8726 params->dtim_period);
8727#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008728
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308729 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008730 {
8731 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308732 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008733 return -EINVAL;
8734 }
8735 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008737 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8738#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8739 params->channel, params->channel_type);
8740#else
8741 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8742#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008743#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008744 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308745 params->ssid_len, params->hidden_ssid,
8746 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008747 }
8748
8749 EXIT();
8750 return status;
8751}
8752
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308753static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8754 struct net_device *dev,
8755 struct cfg80211_ap_settings *params)
8756{
8757 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008758
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308759 vos_ssr_protect(__func__);
8760 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8761 vos_ssr_unprotect(__func__);
8762
8763 return ret;
8764}
8765
8766static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008767 struct net_device *dev,
8768 struct cfg80211_beacon_data *params)
8769{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308771 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308772 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008773
8774 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308775
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308776 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8777 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8778 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008779 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008780 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308781
8782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8783 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308784 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008785 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308786 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008787 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008788
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308789 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008790 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308791 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008792 {
8793 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308794
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008795 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308796
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008797 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308798 {
8799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8800 FL("session(%d) beacon data points to NULL"),
8801 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008802 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308803 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008804
8805 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8806
8807 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308808 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008809 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008810 return -EINVAL;
8811 }
8812
8813 pAdapter->sessionCtx.ap.beacon = new;
8814
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308815 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8816 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008817 }
8818
8819 EXIT();
8820 return status;
8821}
8822
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308823static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8824 struct net_device *dev,
8825 struct cfg80211_beacon_data *params)
8826{
8827 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008828
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308829 vos_ssr_protect(__func__);
8830 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8831 vos_ssr_unprotect(__func__);
8832
8833 return ret;
8834}
8835
8836#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008837
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308838static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 struct net_device *dev,
8840 struct bss_parameters *params)
8841{
8842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308843 hdd_context_t *pHddCtx;
8844 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008845
8846 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308847
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308848 if (NULL == pAdapter)
8849 {
8850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8851 "%s: HDD adapter is Null", __func__);
8852 return -ENODEV;
8853 }
8854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308855 ret = wlan_hdd_validate_context(pHddCtx);
8856 if (0 != ret)
8857 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308858 return ret;
8859 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8861 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8862 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308863 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8864 __func__, hdd_device_modetoString(pAdapter->device_mode),
8865 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008866
8867 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308869 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008870 {
8871 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8872 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 {
8875 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 }
8878
8879 EXIT();
8880 return 0;
8881}
8882
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308883static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8884 struct net_device *dev,
8885 struct bss_parameters *params)
8886{
8887 int ret;
8888
8889 vos_ssr_protect(__func__);
8890 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8891 vos_ssr_unprotect(__func__);
8892
8893 return ret;
8894}
Kiet Lam10841362013-11-01 11:36:50 +05308895/* FUNCTION: wlan_hdd_change_country_code_cd
8896* to wait for contry code completion
8897*/
8898void* wlan_hdd_change_country_code_cb(void *pAdapter)
8899{
8900 hdd_adapter_t *call_back_pAdapter = pAdapter;
8901 complete(&call_back_pAdapter->change_country_code);
8902 return NULL;
8903}
8904
Jeff Johnson295189b2012-06-20 16:38:30 -07008905/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308906 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8908 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308909int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 struct net_device *ndev,
8911 enum nl80211_iftype type,
8912 u32 *flags,
8913 struct vif_params *params
8914 )
8915{
8916 struct wireless_dev *wdev;
8917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008918 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008919 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 tCsrRoamProfile *pRoamProfile = NULL;
8921 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308922 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 eMib_dot11DesiredBssType connectedBssType;
8924 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308925 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008926
8927 ENTER();
8928
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308929 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008930 {
8931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8932 "%s: Adapter context is null", __func__);
8933 return VOS_STATUS_E_FAILURE;
8934 }
8935
8936 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8937 if (!pHddCtx)
8938 {
8939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8940 "%s: HDD context is null", __func__);
8941 return VOS_STATUS_E_FAILURE;
8942 }
8943
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308944 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8945 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8946 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308947 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308948 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308950 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 }
8952
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8954 __func__, hdd_device_modetoString(pAdapter->device_mode),
8955 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
Agarwal Ashish51325b52014-06-16 16:50:49 +05308957 if (vos_max_concurrent_connections_reached()) {
8958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8959 return -EINVAL;
8960 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308961 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 wdev = ndev->ieee80211_ptr;
8963
8964#ifdef WLAN_BTAMP_FEATURE
8965 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8966 (NL80211_IFTYPE_ADHOC == type)||
8967 (NL80211_IFTYPE_AP == type)||
8968 (NL80211_IFTYPE_P2P_GO == type))
8969 {
8970 pHddCtx->isAmpAllowed = VOS_FALSE;
8971 // stop AMP traffic
8972 status = WLANBAP_StopAmp();
8973 if(VOS_STATUS_SUCCESS != status )
8974 {
8975 pHddCtx->isAmpAllowed = VOS_TRUE;
8976 hddLog(VOS_TRACE_LEVEL_FATAL,
8977 "%s: Failed to stop AMP", __func__);
8978 return -EINVAL;
8979 }
8980 }
8981#endif //WLAN_BTAMP_FEATURE
8982 /* Reset the current device mode bit mask*/
8983 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8984
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308985 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8986 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8987 (type == NL80211_IFTYPE_P2P_GO)))
8988 {
8989 /* Notify Mode change in case of concurrency.
8990 * Below function invokes TDLS teardown Functionality Since TDLS is
8991 * not Supported in case of concurrency i.e Once P2P session
8992 * is detected disable offchannel and teardown TDLS links
8993 */
8994 hddLog(LOG1,
8995 FL("Device mode = %d Interface type = %d"),
8996 pAdapter->device_mode, type);
8997 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8998 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308999
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07009002 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 )
9004 {
9005 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009006 if (!pWextState)
9007 {
9008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9009 "%s: pWextState is null", __func__);
9010 return VOS_STATUS_E_FAILURE;
9011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 pRoamProfile = &pWextState->roamProfile;
9013 LastBSSType = pRoamProfile->BSSType;
9014
9015 switch (type)
9016 {
9017 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 hddLog(VOS_TRACE_LEVEL_INFO,
9020 "%s: setting interface Type to INFRASTRUCTURE", __func__);
9021 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009022#ifdef WLAN_FEATURE_11AC
9023 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
9024 {
9025 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
9026 }
9027#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309028 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07009029 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009031 //Check for sub-string p2p to confirm its a p2p interface
9032 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309033 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05309034#ifdef FEATURE_WLAN_TDLS
9035 mutex_lock(&pHddCtx->tdls_lock);
9036 wlan_hdd_tdls_exit(pAdapter, TRUE);
9037 mutex_unlock(&pHddCtx->tdls_lock);
9038#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009039 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9040 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9041 }
9042 else
9043 {
9044 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009046 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05309048
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 case NL80211_IFTYPE_ADHOC:
9050 hddLog(VOS_TRACE_LEVEL_INFO,
9051 "%s: setting interface Type to ADHOC", __func__);
9052 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
9053 pRoamProfile->phyMode =
9054 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07009055 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05309057 hdd_set_ibss_ops( pAdapter );
9058 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05309059
9060 status = hdd_sta_id_hash_attach(pAdapter);
9061 if (VOS_STATUS_SUCCESS != status) {
9062 hddLog(VOS_TRACE_LEVEL_ERROR,
9063 FL("Failed to initialize hash for IBSS"));
9064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 break;
9066
9067 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 {
9070 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9071 "%s: setting interface Type to %s", __func__,
9072 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
9073
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009074 //Cancel any remain on channel for GO mode
9075 if (NL80211_IFTYPE_P2P_GO == type)
9076 {
9077 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
9078 }
Mohit Khanna0f232092012-09-11 14:46:08 -07009079 if (NL80211_IFTYPE_AP == type)
9080 {
9081 /* As Loading WLAN Driver one interface being created for p2p device
9082 * address. This will take one HW STA and the max number of clients
9083 * that can connect to softAP will be reduced by one. so while changing
9084 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
9085 * interface as it is not required in SoftAP mode.
9086 */
9087
9088 // Get P2P Adapter
9089 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
9090
9091 if (pP2pAdapter)
9092 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309093 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05309094 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07009095 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
9096 }
9097 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05309098 //Disable IMPS & BMPS for SAP/GO
9099 if(VOS_STATUS_E_FAILURE ==
9100 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
9101 {
9102 //Fail to Exit BMPS
9103 VOS_ASSERT(0);
9104 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05309105
9106 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
9107
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309108#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07009109
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309110 /* A Mutex Lock is introduced while changing the mode to
9111 * protect the concurrent access for the Adapters by TDLS
9112 * module.
9113 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309114 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05309117 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9120 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309121#ifdef FEATURE_WLAN_TDLS
9122 mutex_unlock(&pHddCtx->tdls_lock);
9123#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009124 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
9125 (pConfig->apRandomBssidEnabled))
9126 {
9127 /* To meet Android requirements create a randomized
9128 MAC address of the form 02:1A:11:Fx:xx:xx */
9129 get_random_bytes(&ndev->dev_addr[3], 3);
9130 ndev->dev_addr[0] = 0x02;
9131 ndev->dev_addr[1] = 0x1A;
9132 ndev->dev_addr[2] = 0x11;
9133 ndev->dev_addr[3] |= 0xF0;
9134 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
9135 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08009136 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
9137 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009138 }
9139
Jeff Johnson295189b2012-06-20 16:38:30 -07009140 hdd_set_ap_ops( pAdapter->dev );
9141
Kiet Lam10841362013-11-01 11:36:50 +05309142 /* This is for only SAP mode where users can
9143 * control country through ini.
9144 * P2P GO follows station country code
9145 * acquired during the STA scanning. */
9146 if((NL80211_IFTYPE_AP == type) &&
9147 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
9148 {
9149 int status = 0;
9150 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
9151 "%s: setting country code from INI ", __func__);
9152 init_completion(&pAdapter->change_country_code);
9153 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
9154 (void *)(tSmeChangeCountryCallback)
9155 wlan_hdd_change_country_code_cb,
9156 pConfig->apCntryCode, pAdapter,
9157 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309158 eSIR_FALSE,
9159 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05309160 if (eHAL_STATUS_SUCCESS == status)
9161 {
9162 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309163 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05309164 &pAdapter->change_country_code,
9165 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309166 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05309167 {
9168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309169 FL("SME Timed out while setting country code %ld"),
9170 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08009171
9172 if (pHddCtx->isLogpInProgress)
9173 {
9174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9175 "%s: LOGP in Progress. Ignore!!!", __func__);
9176 return -EAGAIN;
9177 }
Kiet Lam10841362013-11-01 11:36:50 +05309178 }
9179 }
9180 else
9181 {
9182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009183 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05309184 return -EINVAL;
9185 }
9186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 status = hdd_init_ap_mode(pAdapter);
9188 if(status != VOS_STATUS_SUCCESS)
9189 {
9190 hddLog(VOS_TRACE_LEVEL_FATAL,
9191 "%s: Error initializing the ap mode", __func__);
9192 return -EINVAL;
9193 }
9194 hdd_set_conparam(1);
9195
Nirav Shah7e3c8132015-06-22 23:51:42 +05309196 status = hdd_sta_id_hash_attach(pAdapter);
9197 if (VOS_STATUS_SUCCESS != status)
9198 {
9199 hddLog(VOS_TRACE_LEVEL_ERROR,
9200 FL("Failed to initialize hash for AP"));
9201 return -EINVAL;
9202 }
9203
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 /*interface type changed update in wiphy structure*/
9205 if(wdev)
9206 {
9207 wdev->iftype = type;
9208 pHddCtx->change_iface = type;
9209 }
9210 else
9211 {
9212 hddLog(VOS_TRACE_LEVEL_ERROR,
9213 "%s: ERROR !!!! Wireless dev is NULL", __func__);
9214 return -EINVAL;
9215 }
9216 goto done;
9217 }
9218
9219 default:
9220 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9221 __func__);
9222 return -EOPNOTSUPP;
9223 }
9224 }
9225 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 )
9228 {
9229 switch(type)
9230 {
9231 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05309234
9235 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309236#ifdef FEATURE_WLAN_TDLS
9237
9238 /* A Mutex Lock is introduced while changing the mode to
9239 * protect the concurrent access for the Adapters by TDLS
9240 * module.
9241 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309242 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309243#endif
c_hpothu002231a2015-02-05 14:58:51 +05309244 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009246 //Check for sub-string p2p to confirm its a p2p interface
9247 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009248 {
9249 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9250 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9251 }
9252 else
9253 {
9254 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 hdd_set_conparam(0);
9258 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9260 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309261#ifdef FEATURE_WLAN_TDLS
9262 mutex_unlock(&pHddCtx->tdls_lock);
9263#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309264 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 if( VOS_STATUS_SUCCESS != status )
9266 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009267 /* In case of JB, for P2P-GO, only change interface will be called,
9268 * This is the right place to enable back bmps_imps()
9269 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309270 if (pHddCtx->hdd_wlan_suspended)
9271 {
9272 hdd_set_pwrparams(pHddCtx);
9273 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009274 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 goto done;
9276 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9280 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 goto done;
9282 default:
9283 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9284 __func__);
9285 return -EOPNOTSUPP;
9286
9287 }
9288
9289 }
9290 else
9291 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309292 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9293 __func__, hdd_device_modetoString(pAdapter->device_mode),
9294 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 return -EOPNOTSUPP;
9296 }
9297
9298
9299 if(pRoamProfile)
9300 {
9301 if ( LastBSSType != pRoamProfile->BSSType )
9302 {
9303 /*interface type changed update in wiphy structure*/
9304 wdev->iftype = type;
9305
9306 /*the BSS mode changed, We need to issue disconnect
9307 if connected or in IBSS disconnect state*/
9308 if ( hdd_connGetConnectedBssType(
9309 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9310 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9311 {
9312 /*need to issue a disconnect to CSR.*/
9313 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9314 if( eHAL_STATUS_SUCCESS ==
9315 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9316 pAdapter->sessionId,
9317 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9318 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309319 ret = wait_for_completion_interruptible_timeout(
9320 &pAdapter->disconnect_comp_var,
9321 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9322 if (ret <= 0)
9323 {
9324 hddLog(VOS_TRACE_LEVEL_ERROR,
9325 FL("wait on disconnect_comp_var failed %ld"), ret);
9326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 }
9328 }
9329 }
9330 }
9331
9332done:
9333 /*set bitmask based on updated value*/
9334 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009335
9336 /* Only STA mode support TM now
9337 * all other mode, TM feature should be disabled */
9338 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9339 (~VOS_STA & pHddCtx->concurrency_mode) )
9340 {
9341 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9342 }
9343
Jeff Johnson295189b2012-06-20 16:38:30 -07009344#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309345 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309346 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 {
9348 //we are ok to do AMP
9349 pHddCtx->isAmpAllowed = VOS_TRUE;
9350 }
9351#endif //WLAN_BTAMP_FEATURE
9352 EXIT();
9353 return 0;
9354}
9355
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309356/*
9357 * FUNCTION: wlan_hdd_cfg80211_change_iface
9358 * wrapper function to protect the actual implementation from SSR.
9359 */
9360int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9361 struct net_device *ndev,
9362 enum nl80211_iftype type,
9363 u32 *flags,
9364 struct vif_params *params
9365 )
9366{
9367 int ret;
9368
9369 vos_ssr_protect(__func__);
9370 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9371 vos_ssr_unprotect(__func__);
9372
9373 return ret;
9374}
9375
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009376#ifdef FEATURE_WLAN_TDLS
9377static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309378 struct net_device *dev,
9379#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9380 const u8 *mac,
9381#else
9382 u8 *mac,
9383#endif
9384 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009385{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009386 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009387 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309388 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309389 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309390 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309391 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009392
9393 ENTER();
9394
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309395 if (!dev) {
9396 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9397 return -EINVAL;
9398 }
9399
9400 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9401 if (!pAdapter) {
9402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9403 return -EINVAL;
9404 }
9405
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309406 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009407 {
9408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9409 "Invalid arguments");
9410 return -EINVAL;
9411 }
Hoonki Lee27511902013-03-14 18:19:06 -07009412
9413 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9414 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9415 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009417 "%s: TDLS mode is disabled OR not enabled in FW."
9418 MAC_ADDRESS_STR " Request declined.",
9419 __func__, MAC_ADDR_ARRAY(mac));
9420 return -ENOTSUPP;
9421 }
9422
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009423 if (pHddCtx->isLogpInProgress)
9424 {
9425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9426 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309427 wlan_hdd_tdls_set_link_status(pAdapter,
9428 mac,
9429 eTDLS_LINK_IDLE,
9430 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009431 return -EBUSY;
9432 }
9433
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309434 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309435 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009436
9437 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009439 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9440 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309441 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009442 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009443 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309444 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009445
9446 /* in add station, we accept existing valid staId if there is */
9447 if ((0 == update) &&
9448 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9449 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009450 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009452 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009453 " link_status %d. staId %d. add station ignored.",
9454 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9455 return 0;
9456 }
9457 /* in change station, we accept only when staId is valid */
9458 if ((1 == update) &&
9459 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9460 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9461 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009463 "%s: " MAC_ADDRESS_STR
9464 " link status %d. staId %d. change station %s.",
9465 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9466 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9467 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009468 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009469
9470 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309471 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009472 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9474 "%s: " MAC_ADDRESS_STR
9475 " TDLS setup is ongoing. Request declined.",
9476 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009477 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009478 }
9479
9480 /* first to check if we reached to maximum supported TDLS peer.
9481 TODO: for now, return -EPERM looks working fine,
9482 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309483 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9484 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009485 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9487 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309488 " TDLS Max peer already connected. Request declined."
9489 " Num of peers (%d), Max allowed (%d).",
9490 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9491 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009492 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009493 }
9494 else
9495 {
9496 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309497 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009498 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009499 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9501 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9502 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009503 return -EPERM;
9504 }
9505 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009506 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309507 wlan_hdd_tdls_set_link_status(pAdapter,
9508 mac,
9509 eTDLS_LINK_CONNECTING,
9510 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009511
Jeff Johnsond75fe012013-04-06 10:53:06 -07009512 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309513 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009514 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009516 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009517 if(StaParams->htcap_present)
9518 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009520 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009522 "ht_capa->extended_capabilities: %0x",
9523 StaParams->HTCap.extendedHtCapInfo);
9524 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009526 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009528 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009529 if(StaParams->vhtcap_present)
9530 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009532 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9533 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9534 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9535 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009536 {
9537 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009539 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009541 "[%d]: %x ", i, StaParams->supported_rates[i]);
9542 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009543 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309544 else if ((1 == update) && (NULL == StaParams))
9545 {
9546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9547 "%s : update is true, but staParams is NULL. Error!", __func__);
9548 return -EPERM;
9549 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009550
9551 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9552
9553 if (!update)
9554 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309555 /*Before adding sta make sure that device exited from BMPS*/
9556 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9557 {
9558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9559 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9560 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9561 if (status != VOS_STATUS_SUCCESS) {
9562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9563 }
9564 }
9565
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309566 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009567 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309568 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309569 hddLog(VOS_TRACE_LEVEL_ERROR,
9570 FL("Failed to add TDLS peer STA. Enable Bmps"));
9571 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309572 return -EPERM;
9573 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009574 }
9575 else
9576 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309577 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009578 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309579 if (ret != eHAL_STATUS_SUCCESS) {
9580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9581 return -EPERM;
9582 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009583 }
9584
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309585 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009586 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9587
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309588 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009589 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309591 "%s: timeout waiting for tdls add station indication %ld",
9592 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009593 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009594 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309595
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009596 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9597 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009599 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009600 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009601 }
9602
9603 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009604
9605error:
Atul Mittal115287b2014-07-08 13:26:33 +05309606 wlan_hdd_tdls_set_link_status(pAdapter,
9607 mac,
9608 eTDLS_LINK_IDLE,
9609 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009610 return -EPERM;
9611
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009612}
9613#endif
9614
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309615static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309617#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9618 const u8 *mac,
9619#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 struct station_parameters *params)
9623{
9624 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309625 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309626 hdd_context_t *pHddCtx;
9627 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309629 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009630#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009631 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009632 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309633 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009634#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009635
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309636 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309637
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309638 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309639 if ((NULL == pAdapter))
9640 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309642 "invalid adapter ");
9643 return -EINVAL;
9644 }
9645
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309646 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9647 TRACE_CODE_HDD_CHANGE_STATION,
9648 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309649 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309650
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309651 ret = wlan_hdd_validate_context(pHddCtx);
9652 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309653 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309654 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309655 }
9656
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309657 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9658
9659 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009660 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9662 "invalid HDD station context");
9663 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9666
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009667 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9668 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009670 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309672 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 WLANTL_STA_AUTHENTICATED);
9674
Gopichand Nakkala29149562013-05-10 21:43:41 +05309675 if (status != VOS_STATUS_SUCCESS)
9676 {
9677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9678 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9679 return -EINVAL;
9680 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 }
9682 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009683 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9684 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309685#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009686 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9687 StaParams.capability = params->capability;
9688 StaParams.uapsd_queues = params->uapsd_queues;
9689 StaParams.max_sp = params->max_sp;
9690
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309691 /* Convert (first channel , number of channels) tuple to
9692 * the total list of channels. This goes with the assumption
9693 * that if the first channel is < 14, then the next channels
9694 * are an incremental of 1 else an incremental of 4 till the number
9695 * of channels.
9696 */
9697 if (0 != params->supported_channels_len) {
9698 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9699 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9700 {
9701 int wifi_chan_index;
9702 StaParams.supported_channels[j] = params->supported_channels[i];
9703 wifi_chan_index =
9704 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9705 no_of_channels = params->supported_channels[i+1];
9706 for(k=1; k <= no_of_channels; k++)
9707 {
9708 StaParams.supported_channels[j+1] =
9709 StaParams.supported_channels[j] + wifi_chan_index;
9710 j+=1;
9711 }
9712 }
9713 StaParams.supported_channels_len = j;
9714 }
9715 vos_mem_copy(StaParams.supported_oper_classes,
9716 params->supported_oper_classes,
9717 params->supported_oper_classes_len);
9718 StaParams.supported_oper_classes_len =
9719 params->supported_oper_classes_len;
9720
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009721 if (0 != params->ext_capab_len)
9722 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9723 sizeof(StaParams.extn_capability));
9724
9725 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009726 {
9727 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009728 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009729 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009730
9731 StaParams.supported_rates_len = params->supported_rates_len;
9732
9733 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9734 * The supported_rates array , for all the structures propogating till Add Sta
9735 * to the firmware has to be modified , if the supplicant (ieee80211) is
9736 * modified to send more rates.
9737 */
9738
9739 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9740 */
9741 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9742 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9743
9744 if (0 != StaParams.supported_rates_len) {
9745 int i = 0;
9746 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9747 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009749 "Supported Rates with Length %d", StaParams.supported_rates_len);
9750 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009752 "[%d]: %0x", i, StaParams.supported_rates[i]);
9753 }
9754
9755 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009756 {
9757 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009758 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009759 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009760
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009761 if (0 != params->ext_capab_len ) {
9762 /*Define A Macro : TODO Sunil*/
9763 if ((1<<4) & StaParams.extn_capability[3]) {
9764 isBufSta = 1;
9765 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309766 /* TDLS Channel Switching Support */
9767 if ((1<<6) & StaParams.extn_capability[3]) {
9768 isOffChannelSupported = 1;
9769 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009770 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309771 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9772 &StaParams, isBufSta,
9773 isOffChannelSupported);
9774
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309775 if (VOS_STATUS_SUCCESS != status) {
9776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9777 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9778 return -EINVAL;
9779 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009780 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9781
9782 if (VOS_STATUS_SUCCESS != status) {
9783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9784 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9785 return -EINVAL;
9786 }
9787 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009788#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309789 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009790 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 return status;
9792}
9793
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9795static int wlan_hdd_change_station(struct wiphy *wiphy,
9796 struct net_device *dev,
9797 const u8 *mac,
9798 struct station_parameters *params)
9799#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309800static int wlan_hdd_change_station(struct wiphy *wiphy,
9801 struct net_device *dev,
9802 u8 *mac,
9803 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309804#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309805{
9806 int ret;
9807
9808 vos_ssr_protect(__func__);
9809 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9810 vos_ssr_unprotect(__func__);
9811
9812 return ret;
9813}
9814
Jeff Johnson295189b2012-06-20 16:38:30 -07009815/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309816 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009817 * This function is used to initialize the key information
9818 */
9819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309820static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 struct net_device *ndev,
9822 u8 key_index, bool pairwise,
9823 const u8 *mac_addr,
9824 struct key_params *params
9825 )
9826#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309827static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 struct net_device *ndev,
9829 u8 key_index, const u8 *mac_addr,
9830 struct key_params *params
9831 )
9832#endif
9833{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 tCsrRoamSetKey setKey;
9836 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309837 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009838 v_U32_t roamId= 0xFF;
9839 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 hdd_hostapd_state_t *pHostapdState;
9841 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009842 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309843 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009844
9845 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309846
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309847 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9848 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9849 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309850 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9851 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309852 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309854 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009855 }
9856
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309857 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9858 __func__, hdd_device_modetoString(pAdapter->device_mode),
9859 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860
9861 if (CSR_MAX_NUM_KEY <= key_index)
9862 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 key_index);
9865
9866 return -EINVAL;
9867 }
9868
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009869 if (CSR_MAX_KEY_LEN < params->key_len)
9870 {
9871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9872 params->key_len);
9873
9874 return -EINVAL;
9875 }
9876
9877 hddLog(VOS_TRACE_LEVEL_INFO,
9878 "%s: called with key index = %d & key length %d",
9879 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009880
9881 /*extract key idx, key len and key*/
9882 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9883 setKey.keyId = key_index;
9884 setKey.keyLength = params->key_len;
9885 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9886
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009887 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 {
9889 case WLAN_CIPHER_SUITE_WEP40:
9890 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9891 break;
9892
9893 case WLAN_CIPHER_SUITE_WEP104:
9894 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9895 break;
9896
9897 case WLAN_CIPHER_SUITE_TKIP:
9898 {
9899 u8 *pKey = &setKey.Key[0];
9900 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9901
9902 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9903
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009904 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009905
9906 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009907 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 |--------------|----------|----------|
9909 <---16bytes---><--8bytes--><--8bytes-->
9910
9911 */
9912 /*Sme expects the 32 bytes key to be in the below order
9913
9914 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009915 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 |--------------|----------|----------|
9917 <---16bytes---><--8bytes--><--8bytes-->
9918 */
9919 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009920 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009921
9922 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009923 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009924
9925 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009926 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009927
9928
9929 break;
9930 }
9931
9932 case WLAN_CIPHER_SUITE_CCMP:
9933 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9934 break;
9935
9936#ifdef FEATURE_WLAN_WAPI
9937 case WLAN_CIPHER_SUITE_SMS4:
9938 {
9939 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9940 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9941 params->key, params->key_len);
9942 return 0;
9943 }
9944#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009945
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009946#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 case WLAN_CIPHER_SUITE_KRK:
9948 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9949 break;
9950#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009951
9952#ifdef WLAN_FEATURE_11W
9953 case WLAN_CIPHER_SUITE_AES_CMAC:
9954 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009955 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009956#endif
9957
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309961 status = -EOPNOTSUPP;
9962 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 }
9964
9965 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9966 __func__, setKey.encType);
9967
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009968 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9970 (!pairwise)
9971#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009972 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009973#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009974 )
9975 {
9976 /* set group key*/
9977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9978 "%s- %d: setting Broadcast key",
9979 __func__, __LINE__);
9980 setKey.keyDirection = eSIR_RX_ONLY;
9981 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9982 }
9983 else
9984 {
9985 /* set pairwise key*/
9986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9987 "%s- %d: setting pairwise key",
9988 __func__, __LINE__);
9989 setKey.keyDirection = eSIR_TX_RX;
9990 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9991 }
9992 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9993 {
9994 setKey.keyDirection = eSIR_TX_RX;
9995 /*Set the group key*/
9996 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9997 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009998
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009999 if ( 0 != status )
10000 {
10001 hddLog(VOS_TRACE_LEVEL_ERROR,
10002 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010003 status = -EINVAL;
10004 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010005 }
10006 /*Save the keys here and call sme_RoamSetKey for setting
10007 the PTK after peer joins the IBSS network*/
10008 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
10009 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010010 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010011 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053010012 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
10013 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
10014 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010016 if( pHostapdState->bssState == BSS_START )
10017 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010018 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10019 vos_status = wlan_hdd_check_ula_done(pAdapter);
10020
10021 if ( vos_status != VOS_STATUS_SUCCESS )
10022 {
10023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10024 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
10025 __LINE__, vos_status );
10026
10027 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10028
10029 status = -EINVAL;
10030 goto end;
10031 }
10032
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 status = WLANSAP_SetKeySta( pVosContext, &setKey);
10034
10035 if ( status != eHAL_STATUS_SUCCESS )
10036 {
10037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10038 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10039 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010040 status = -EINVAL;
10041 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 }
10043 }
10044
10045 /* Saving WEP keys */
10046 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
10047 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
10048 {
10049 //Save the wep key in ap context. Issue setkey after the BSS is started.
10050 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10051 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
10052 }
10053 else
10054 {
10055 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010056 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
10058 }
10059 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010060 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
10061 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 {
10063 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10064 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10065
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10067 if (!pairwise)
10068#else
10069 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
10070#endif
10071 {
10072 /* set group key*/
10073 if (pHddStaCtx->roam_info.deferKeyComplete)
10074 {
10075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10076 "%s- %d: Perform Set key Complete",
10077 __func__, __LINE__);
10078 hdd_PerformRoamSetKeyComplete(pAdapter);
10079 }
10080 }
10081
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
10083
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080010084 pWextState->roamProfile.Keys.defaultIndex = key_index;
10085
10086
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010087 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 params->key, params->key_len);
10089
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010090
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10092
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010095 __func__, setKey.peerMac[0], setKey.peerMac[1],
10096 setKey.peerMac[2], setKey.peerMac[3],
10097 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 setKey.keyDirection);
10099
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010100 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053010101
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010102 if ( vos_status != VOS_STATUS_SUCCESS )
10103 {
10104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
10106 __LINE__, vos_status );
10107
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010108 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010109
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010110 status = -EINVAL;
10111 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010112
10113 }
10114
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010115#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010116 /* The supplicant may attempt to set the PTK once pre-authentication
10117 is done. Save the key in the UMAC and include it in the ADD BSS
10118 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010119 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010120 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010121 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010122 hddLog(VOS_TRACE_LEVEL_INFO_MED,
10123 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010124 status = 0;
10125 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010126 }
10127 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
10128 {
10129 hddLog(VOS_TRACE_LEVEL_ERROR,
10130 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010131 status = -EINVAL;
10132 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010133 }
10134#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070010135
10136 /* issue set key request to SME*/
10137 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10138 pAdapter->sessionId, &setKey, &roamId );
10139
10140 if ( 0 != status )
10141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
10144 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010145 status = -EINVAL;
10146 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 }
10148
10149
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010150 /* in case of IBSS as there was no information available about WEP keys during
10151 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010153 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
10154 !( ( IW_AUTH_KEY_MGMT_802_1X
10155 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
10157 )
10158 &&
10159 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
10160 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
10161 )
10162 )
10163 {
10164 setKey.keyDirection = eSIR_RX_ONLY;
10165 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10166
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010167 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010169 __func__, setKey.peerMac[0], setKey.peerMac[1],
10170 setKey.peerMac[2], setKey.peerMac[3],
10171 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 setKey.keyDirection);
10173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010174 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 pAdapter->sessionId, &setKey, &roamId );
10176
10177 if ( 0 != status )
10178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010179 hddLog(VOS_TRACE_LEVEL_ERROR,
10180 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 __func__, status);
10182 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010183 status = -EINVAL;
10184 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 }
10186 }
10187 }
10188
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010189end:
10190 /* Need to clear any trace of key value in the memory.
10191 * Thus zero out the memory even though it is local
10192 * variable.
10193 */
10194 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010195 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010196 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010197}
10198
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10200static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10201 struct net_device *ndev,
10202 u8 key_index, bool pairwise,
10203 const u8 *mac_addr,
10204 struct key_params *params
10205 )
10206#else
10207static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10208 struct net_device *ndev,
10209 u8 key_index, const u8 *mac_addr,
10210 struct key_params *params
10211 )
10212#endif
10213{
10214 int ret;
10215 vos_ssr_protect(__func__);
10216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10217 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
10218 mac_addr, params);
10219#else
10220 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
10221 params);
10222#endif
10223 vos_ssr_unprotect(__func__);
10224
10225 return ret;
10226}
10227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010229 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010230 * This function is used to get the key information
10231 */
10232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010233static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010234 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010236 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 const u8 *mac_addr, void *cookie,
10238 void (*callback)(void *cookie, struct key_params*)
10239 )
10240#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010241static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010242 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 struct net_device *ndev,
10244 u8 key_index, const u8 *mac_addr, void *cookie,
10245 void (*callback)(void *cookie, struct key_params*)
10246 )
10247#endif
10248{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010249 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010250 hdd_wext_state_t *pWextState = NULL;
10251 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010253 hdd_context_t *pHddCtx;
10254 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010255
10256 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010258 if (NULL == pAdapter)
10259 {
10260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10261 "%s: HDD adapter is Null", __func__);
10262 return -ENODEV;
10263 }
10264
10265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10266 ret = wlan_hdd_validate_context(pHddCtx);
10267 if (0 != ret)
10268 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010269 return ret;
10270 }
10271
10272 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10273 pRoamProfile = &(pWextState->roamProfile);
10274
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010275 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10276 __func__, hdd_device_modetoString(pAdapter->device_mode),
10277 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010278
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 memset(&params, 0, sizeof(params));
10280
10281 if (CSR_MAX_NUM_KEY <= key_index)
10282 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010285 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010286
10287 switch(pRoamProfile->EncryptionType.encryptionType[0])
10288 {
10289 case eCSR_ENCRYPT_TYPE_NONE:
10290 params.cipher = IW_AUTH_CIPHER_NONE;
10291 break;
10292
10293 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10294 case eCSR_ENCRYPT_TYPE_WEP40:
10295 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10296 break;
10297
10298 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10299 case eCSR_ENCRYPT_TYPE_WEP104:
10300 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10301 break;
10302
10303 case eCSR_ENCRYPT_TYPE_TKIP:
10304 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10305 break;
10306
10307 case eCSR_ENCRYPT_TYPE_AES:
10308 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10309 break;
10310
10311 default:
10312 params.cipher = IW_AUTH_CIPHER_NONE;
10313 break;
10314 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010315
c_hpothuaaf19692014-05-17 17:01:48 +053010316 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10317 TRACE_CODE_HDD_CFG80211_GET_KEY,
10318 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010319
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10321 params.seq_len = 0;
10322 params.seq = NULL;
10323 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10324 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010325 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 return 0;
10327}
10328
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10330static int wlan_hdd_cfg80211_get_key(
10331 struct wiphy *wiphy,
10332 struct net_device *ndev,
10333 u8 key_index, bool pairwise,
10334 const u8 *mac_addr, void *cookie,
10335 void (*callback)(void *cookie, struct key_params*)
10336 )
10337#else
10338static int wlan_hdd_cfg80211_get_key(
10339 struct wiphy *wiphy,
10340 struct net_device *ndev,
10341 u8 key_index, const u8 *mac_addr, void *cookie,
10342 void (*callback)(void *cookie, struct key_params*)
10343 )
10344#endif
10345{
10346 int ret;
10347
10348 vos_ssr_protect(__func__);
10349#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10350 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10351 mac_addr, cookie, callback);
10352#else
10353 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10354 callback);
10355#endif
10356 vos_ssr_unprotect(__func__);
10357
10358 return ret;
10359}
10360
Jeff Johnson295189b2012-06-20 16:38:30 -070010361/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010362 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 * This function is used to delete the key information
10364 */
10365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010366static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010368 u8 key_index,
10369 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 const u8 *mac_addr
10371 )
10372#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010373static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 struct net_device *ndev,
10375 u8 key_index,
10376 const u8 *mac_addr
10377 )
10378#endif
10379{
10380 int status = 0;
10381
10382 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010383 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010384 //it is observed that this is invalidating peer
10385 //key index whenever re-key is done. This is affecting data link.
10386 //It should be ok to ignore del_key.
10387#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010388 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10389 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010390 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10391 tCsrRoamSetKey setKey;
10392 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 ENTER();
10395
10396 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10397 __func__,pAdapter->device_mode);
10398
10399 if (CSR_MAX_NUM_KEY <= key_index)
10400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 key_index);
10403
10404 return -EINVAL;
10405 }
10406
10407 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10408 setKey.keyId = key_index;
10409
10410 if (mac_addr)
10411 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10412 else
10413 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10414
10415 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10416
10417 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010419 )
10420 {
10421
10422 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10424 if( pHostapdState->bssState == BSS_START)
10425 {
10426 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010427
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 if ( status != eHAL_STATUS_SUCCESS )
10429 {
10430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10431 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10432 __LINE__, status );
10433 }
10434 }
10435 }
10436 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010437 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 )
10439 {
10440 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10441
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010442 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10443
10444 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446 __func__, setKey.peerMac[0], setKey.peerMac[1],
10447 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010449 if(pAdapter->sessionCtx.station.conn_info.connState ==
10450 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010452 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010454
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 if ( 0 != status )
10456 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010457 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 "%s: sme_RoamSetKey failure, returned %d",
10459 __func__, status);
10460 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10461 return -EINVAL;
10462 }
10463 }
10464 }
10465#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010466 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 return status;
10468}
10469
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10471static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10472 struct net_device *ndev,
10473 u8 key_index,
10474 bool pairwise,
10475 const u8 *mac_addr
10476 )
10477#else
10478static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10479 struct net_device *ndev,
10480 u8 key_index,
10481 const u8 *mac_addr
10482 )
10483#endif
10484{
10485 int ret;
10486
10487 vos_ssr_protect(__func__);
10488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10489 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10490 mac_addr);
10491#else
10492 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10493#endif
10494 vos_ssr_unprotect(__func__);
10495
10496 return ret;
10497}
10498
Jeff Johnson295189b2012-06-20 16:38:30 -070010499/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010500 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 * This function is used to set the default tx key index
10502 */
10503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010504static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010505 struct net_device *ndev,
10506 u8 key_index,
10507 bool unicast, bool multicast)
10508#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010509static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 struct net_device *ndev,
10511 u8 key_index)
10512#endif
10513{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010515 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010516 hdd_wext_state_t *pWextState;
10517 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010518 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010519
10520 ENTER();
10521
Gopichand Nakkala29149562013-05-10 21:43:41 +053010522 if ((NULL == pAdapter))
10523 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010525 "invalid adapter");
10526 return -EINVAL;
10527 }
10528
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10530 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10531 pAdapter->sessionId, key_index));
10532
Gopichand Nakkala29149562013-05-10 21:43:41 +053010533 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10534 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10535
10536 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10537 {
10538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10539 "invalid Wext state or HDD context");
10540 return -EINVAL;
10541 }
10542
Arif Hussain6d2a3322013-11-17 19:50:10 -080010543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010544 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010545
Jeff Johnson295189b2012-06-20 16:38:30 -070010546 if (CSR_MAX_NUM_KEY <= key_index)
10547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010549 key_index);
10550
10551 return -EINVAL;
10552 }
10553
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010554 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10555 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010556 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010557 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010558 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010559 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010560
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010563 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010565 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010566 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010567 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010568 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010570 {
10571 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010573
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 tCsrRoamSetKey setKey;
10575 v_U32_t roamId= 0xFF;
10576 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010577
10578 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010580
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 Keys->defaultIndex = (u8)key_index;
10582 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10583 setKey.keyId = key_index;
10584 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010585
10586 vos_mem_copy(&setKey.Key[0],
10587 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589
Gopichand Nakkala29149562013-05-10 21:43:41 +053010590 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010591
10592 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 &pHddStaCtx->conn_info.bssId[0],
10594 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010595
Gopichand Nakkala29149562013-05-10 21:43:41 +053010596 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10597 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10598 eCSR_ENCRYPT_TYPE_WEP104)
10599 {
10600 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10601 even though ap is configured for WEP-40 encryption. In this canse the key length
10602 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10603 type(104) and switching encryption type to 40*/
10604 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10605 eCSR_ENCRYPT_TYPE_WEP40;
10606 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10607 eCSR_ENCRYPT_TYPE_WEP40;
10608 }
10609
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010610 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010612
Jeff Johnson295189b2012-06-20 16:38:30 -070010613 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010614 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010615 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010616
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 if ( 0 != status )
10618 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010619 hddLog(VOS_TRACE_LEVEL_ERROR,
10620 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010621 status);
10622 return -EINVAL;
10623 }
10624 }
10625 }
10626
10627 /* In SoftAp mode setting key direction for default mode */
10628 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10629 {
10630 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10631 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10632 (eCSR_ENCRYPT_TYPE_AES !=
10633 pWextState->roamProfile.EncryptionType.encryptionType[0])
10634 )
10635 {
10636 /* Saving key direction for default key index to TX default */
10637 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10638 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10639 }
10640 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010641 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 return status;
10643}
10644
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10646static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10647 struct net_device *ndev,
10648 u8 key_index,
10649 bool unicast, bool multicast)
10650#else
10651static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10652 struct net_device *ndev,
10653 u8 key_index)
10654#endif
10655{
10656 int ret;
10657 vos_ssr_protect(__func__);
10658#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10659 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10660 multicast);
10661#else
10662 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10663#endif
10664 vos_ssr_unprotect(__func__);
10665
10666 return ret;
10667}
10668
Jeff Johnson295189b2012-06-20 16:38:30 -070010669/*
10670 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10671 * This function is used to inform the BSS details to nl80211 interface.
10672 */
10673static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10674 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10675{
10676 struct net_device *dev = pAdapter->dev;
10677 struct wireless_dev *wdev = dev->ieee80211_ptr;
10678 struct wiphy *wiphy = wdev->wiphy;
10679 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10680 int chan_no;
10681 int ie_length;
10682 const char *ie;
10683 unsigned int freq;
10684 struct ieee80211_channel *chan;
10685 int rssi = 0;
10686 struct cfg80211_bss *bss = NULL;
10687
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 if( NULL == pBssDesc )
10689 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010690 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 return bss;
10692 }
10693
10694 chan_no = pBssDesc->channelId;
10695 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10696 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10697
10698 if( NULL == ie )
10699 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010700 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 return bss;
10702 }
10703
10704#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10705 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10706 {
10707 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10708 }
10709 else
10710 {
10711 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10712 }
10713#else
10714 freq = ieee80211_channel_to_frequency(chan_no);
10715#endif
10716
10717 chan = __ieee80211_get_channel(wiphy, freq);
10718
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010719 if (!chan) {
10720 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10721 return NULL;
10722 }
10723
Abhishek Singhaee43942014-06-16 18:55:47 +053010724 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010725
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010726 return cfg80211_inform_bss(wiphy, chan,
10727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10728 CFG80211_BSS_FTYPE_UNKNOWN,
10729#endif
10730 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010731 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010732 pBssDesc->capabilityInfo,
10733 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010734 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010735}
10736
10737
10738
10739/*
10740 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10741 * This function is used to inform the BSS details to nl80211 interface.
10742 */
10743struct cfg80211_bss*
10744wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10745 tSirBssDescription *bss_desc
10746 )
10747{
10748 /*
10749 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10750 already exists in bss data base of cfg80211 for that particular BSS ID.
10751 Using cfg80211_inform_bss_frame to update the bss entry instead of
10752 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10753 now there is no possibility to get the mgmt(probe response) frame from PE,
10754 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10755 cfg80211_inform_bss_frame.
10756 */
10757 struct net_device *dev = pAdapter->dev;
10758 struct wireless_dev *wdev = dev->ieee80211_ptr;
10759 struct wiphy *wiphy = wdev->wiphy;
10760 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010761#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10762 qcom_ie_age *qie_age = NULL;
10763 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10764#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 const char *ie =
10768 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10769 unsigned int freq;
10770 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010771 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 struct cfg80211_bss *bss_status = NULL;
10773 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10774 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010775 hdd_context_t *pHddCtx;
10776 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010777#ifdef WLAN_OPEN_SOURCE
10778 struct timespec ts;
10779#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010780
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010781
Wilson Yangf80a0542013-10-07 13:02:37 -070010782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10783 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010784 if (0 != status)
10785 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010786 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010787 }
10788
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010789 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010790 if (!mgmt)
10791 {
10792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10793 "%s: memory allocation failed ", __func__);
10794 return NULL;
10795 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010796
Jeff Johnson295189b2012-06-20 16:38:30 -070010797 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010798
10799#ifdef WLAN_OPEN_SOURCE
10800 /* Android does not want the timestamp from the frame.
10801 Instead it wants a monotonic increasing value */
10802 get_monotonic_boottime(&ts);
10803 mgmt->u.probe_resp.timestamp =
10804 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10805#else
10806 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010807 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10808 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010809
10810#endif
10811
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10813 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010814
10815#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10816 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10817 /* Assuming this is the last IE, copy at the end */
10818 ie_length -=sizeof(qcom_ie_age);
10819 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10820 qie_age->element_id = QCOM_VENDOR_IE_ID;
10821 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10822 qie_age->oui_1 = QCOM_OUI1;
10823 qie_age->oui_2 = QCOM_OUI2;
10824 qie_age->oui_3 = QCOM_OUI3;
10825 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10826 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10827#endif
10828
Jeff Johnson295189b2012-06-20 16:38:30 -070010829 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010830 if (bss_desc->fProbeRsp)
10831 {
10832 mgmt->frame_control |=
10833 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10834 }
10835 else
10836 {
10837 mgmt->frame_control |=
10838 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10839 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010840
10841#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010842 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010843 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10844 {
10845 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10846 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010847 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10849
10850 {
10851 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10852 }
10853 else
10854 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10856 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010857 kfree(mgmt);
10858 return NULL;
10859 }
10860#else
10861 freq = ieee80211_channel_to_frequency(chan_no);
10862#endif
10863 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010864 /*when the band is changed on the fly using the GUI, three things are done
10865 * 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)
10866 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10867 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10868 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10869 * and discards the channels correponding to previous band and calls back with zero bss results.
10870 * 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
10871 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10872 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10873 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10874 * So drop the bss and continue to next bss.
10875 */
10876 if(chan == NULL)
10877 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010879 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010880 return NULL;
10881 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010882 /*To keep the rssi icon of the connected AP in the scan window
10883 *and the rssi icon of the wireless networks in sync
10884 * */
10885 if (( eConnectionState_Associated ==
10886 pAdapter->sessionCtx.station.conn_info.connState ) &&
10887 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10888 pAdapter->sessionCtx.station.conn_info.bssId,
10889 WNI_CFG_BSSID_LEN)) &&
10890 (pHddCtx->hdd_wlan_suspended == FALSE))
10891 {
10892 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10893 rssi = (pAdapter->rssi * 100);
10894 }
10895 else
10896 {
10897 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10898 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010899
Nirav Shah20ac06f2013-12-12 18:14:06 +053010900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010901 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10902 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010903
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10905 frame_len, rssi, GFP_KERNEL);
10906 kfree(mgmt);
10907 return bss_status;
10908}
10909
10910/*
10911 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10912 * This function is used to update the BSS data base of CFG8011
10913 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010914struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 tCsrRoamInfo *pRoamInfo
10916 )
10917{
10918 tCsrRoamConnectedProfile roamProfile;
10919 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10920 struct cfg80211_bss *bss = NULL;
10921
10922 ENTER();
10923
10924 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10925 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10926
10927 if (NULL != roamProfile.pBssDesc)
10928 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010929 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10930 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010931
10932 if (NULL == bss)
10933 {
10934 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10935 __func__);
10936 }
10937
10938 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10939 }
10940 else
10941 {
10942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10943 __func__);
10944 }
10945 return bss;
10946}
10947
10948/*
10949 * FUNCTION: wlan_hdd_cfg80211_update_bss
10950 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010951static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10952 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010953 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010955 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010956 tCsrScanResultInfo *pScanResult;
10957 eHalStatus status = 0;
10958 tScanResultHandle pResult;
10959 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010960 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010961 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010962 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010963
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010964 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10965 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10966 NO_SESSION, pAdapter->sessionId));
10967
Wilson Yangf80a0542013-10-07 13:02:37 -070010968 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10969
10970 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10973 "%s:LOGP in Progress. Ignore!!!",__func__);
10974 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 }
10976
Wilson Yangf80a0542013-10-07 13:02:37 -070010977
10978 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010979 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010980 {
10981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10982 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10983 return VOS_STATUS_E_PERM;
10984 }
10985
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010986 if (pAdapter->request != NULL)
10987 {
10988 if ((pAdapter->request->n_ssids == 1)
10989 && (pAdapter->request->ssids != NULL)
10990 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10991 is_p2p_scan = true;
10992 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 /*
10994 * start getting scan results and populate cgf80211 BSS database
10995 */
10996 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10997
10998 /* no scan results */
10999 if (NULL == pResult)
11000 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011001 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
11002 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011003 wlan_hdd_get_frame_logs(pAdapter,
11004 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 return status;
11006 }
11007
11008 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
11009
11010 while (pScanResult)
11011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011012 /*
11013 * cfg80211_inform_bss() is not updating ie field of bss entry, if
11014 * entry already exists in bss data base of cfg80211 for that
11015 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
11016 * bss entry instead of cfg80211_inform_bss, But this call expects
11017 * mgmt packet as input. As of now there is no possibility to get
11018 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 * ieee80211_mgmt(probe response) and passing to c
11020 * fg80211_inform_bss_frame.
11021 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011022 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
11023 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
11024 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011025 pScanResult = sme_ScanResultGetNext(hHal, pResult);
11026 continue; //Skip the non p2p bss entries
11027 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
11029 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011030
Jeff Johnson295189b2012-06-20 16:38:30 -070011031
11032 if (NULL == bss_status)
11033 {
11034 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011035 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 }
11037 else
11038 {
Yue Maf49ba872013-08-19 12:04:25 -070011039 cfg80211_put_bss(
11040#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
11041 wiphy,
11042#endif
11043 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011044 }
11045
11046 pScanResult = sme_ScanResultGetNext(hHal, pResult);
11047 }
11048
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011049 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011050 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011052}
11053
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011054void
11055hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
11056{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011057 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080011058 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011059} /****** end hddPrintMacAddr() ******/
11060
11061void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011062hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011063{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011064 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011065 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011066 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
11067 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
11068 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011069} /****** end hddPrintPmkId() ******/
11070
11071//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
11072//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
11073
11074//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
11075//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
11076
11077#define dump_bssid(bssid) \
11078 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070011079 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
11080 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011081 }
11082
11083#define dump_pmkid(pMac, pmkid) \
11084 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070011085 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
11086 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011087 }
11088
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070011089#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011090/*
11091 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
11092 * This function is used to notify the supplicant of a new PMKSA candidate.
11093 */
11094int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011095 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011096 int index, bool preauth )
11097{
Jeff Johnsone7245742012-09-05 17:12:55 -070011098#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011099 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011100 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011101
11102 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070011103 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011104
11105 if( NULL == pRoamInfo )
11106 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011107 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011108 return -EINVAL;
11109 }
11110
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011111 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
11112 {
11113 dump_bssid(pRoamInfo->bssid);
11114 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011115 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011116 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011117#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011118 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011119}
11120#endif //FEATURE_WLAN_LFR
11121
Yue Maef608272013-04-08 23:09:17 -070011122#ifdef FEATURE_WLAN_LFR_METRICS
11123/*
11124 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
11125 * 802.11r/LFR metrics reporting function to report preauth initiation
11126 *
11127 */
11128#define MAX_LFR_METRICS_EVENT_LENGTH 100
11129VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
11130 tCsrRoamInfo *pRoamInfo)
11131{
11132 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11133 union iwreq_data wrqu;
11134
11135 ENTER();
11136
11137 if (NULL == pAdapter)
11138 {
11139 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11140 return VOS_STATUS_E_FAILURE;
11141 }
11142
11143 /* create the event */
11144 memset(&wrqu, 0, sizeof(wrqu));
11145 memset(metrics_notification, 0, sizeof(metrics_notification));
11146
11147 wrqu.data.pointer = metrics_notification;
11148 wrqu.data.length = scnprintf(metrics_notification,
11149 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
11150 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11151
11152 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11153
11154 EXIT();
11155
11156 return VOS_STATUS_SUCCESS;
11157}
11158
11159/*
11160 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
11161 * 802.11r/LFR metrics reporting function to report preauth completion
11162 * or failure
11163 */
11164VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
11165 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
11166{
11167 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11168 union iwreq_data wrqu;
11169
11170 ENTER();
11171
11172 if (NULL == pAdapter)
11173 {
11174 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11175 return VOS_STATUS_E_FAILURE;
11176 }
11177
11178 /* create the event */
11179 memset(&wrqu, 0, sizeof(wrqu));
11180 memset(metrics_notification, 0, sizeof(metrics_notification));
11181
11182 scnprintf(metrics_notification, sizeof(metrics_notification),
11183 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
11184 MAC_ADDR_ARRAY(pRoamInfo->bssid));
11185
11186 if (1 == preauth_status)
11187 strncat(metrics_notification, " TRUE", 5);
11188 else
11189 strncat(metrics_notification, " FALSE", 6);
11190
11191 wrqu.data.pointer = metrics_notification;
11192 wrqu.data.length = strlen(metrics_notification);
11193
11194 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11195
11196 EXIT();
11197
11198 return VOS_STATUS_SUCCESS;
11199}
11200
11201/*
11202 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
11203 * 802.11r/LFR metrics reporting function to report handover initiation
11204 *
11205 */
11206VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
11207 tCsrRoamInfo *pRoamInfo)
11208{
11209 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11210 union iwreq_data wrqu;
11211
11212 ENTER();
11213
11214 if (NULL == pAdapter)
11215 {
11216 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11217 return VOS_STATUS_E_FAILURE;
11218 }
11219
11220 /* create the event */
11221 memset(&wrqu, 0, sizeof(wrqu));
11222 memset(metrics_notification, 0, sizeof(metrics_notification));
11223
11224 wrqu.data.pointer = metrics_notification;
11225 wrqu.data.length = scnprintf(metrics_notification,
11226 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
11227 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11228
11229 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11230
11231 EXIT();
11232
11233 return VOS_STATUS_SUCCESS;
11234}
11235#endif
11236
Jeff Johnson295189b2012-06-20 16:38:30 -070011237/*
11238 * FUNCTION: hdd_cfg80211_scan_done_callback
11239 * scanning callback function, called after finishing scan
11240 *
11241 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011242static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11244{
11245 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011246 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011248 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 struct cfg80211_scan_request *req = NULL;
11250 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011251 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011252 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011253 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011254 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011255
11256 ENTER();
11257
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011258 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011259 if (NULL == pHddCtx) {
11260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011261 goto allow_suspend;
11262 }
11263
11264 pScanInfo = &pHddCtx->scan_info;
11265
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 hddLog(VOS_TRACE_LEVEL_INFO,
11267 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011268 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 __func__, halHandle, pContext, (int) scanId, (int) status);
11270
Kiet Lamac06e2c2013-10-23 16:25:07 +053011271 pScanInfo->mScanPendingCounter = 0;
11272
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011274 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 &pScanInfo->scan_req_completion_event,
11276 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011277 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011279 hddLog(VOS_TRACE_LEVEL_ERROR,
11280 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011282 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 }
11284
Yue Maef608272013-04-08 23:09:17 -070011285 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 {
11287 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011288 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 }
11290
11291 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011292 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 {
11294 hddLog(VOS_TRACE_LEVEL_INFO,
11295 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011296 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 (int) scanId);
11298 }
11299
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 pAdapter);
11302
11303 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011304 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011305
11306
11307 /* If any client wait scan result through WEXT
11308 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011309 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 {
11311 /* The other scan request waiting for current scan finish
11312 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011313 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011315 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 }
11317 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011318 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 {
11320 struct net_device *dev = pAdapter->dev;
11321 union iwreq_data wrqu;
11322 int we_event;
11323 char *msg;
11324
11325 memset(&wrqu, '\0', sizeof(wrqu));
11326 we_event = SIOCGIWSCAN;
11327 msg = NULL;
11328 wireless_send_event(dev, we_event, &wrqu, msg);
11329 }
11330 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011331 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011332
11333 /* Get the Scan Req */
11334 req = pAdapter->request;
11335
11336 if (!req)
11337 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011338 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011339 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011340 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011341 }
11342
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011344 /* Scan is no longer pending */
11345 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011346
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011347 /* last_scan_timestamp is used to decide if new scan
11348 * is needed or not on station interface. If last station
11349 * scan time and new station scan time is less then
11350 * last_scan_timestamp ; driver will return cached scan.
11351 */
11352 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11353 {
11354 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11355
11356 if ( req->n_channels )
11357 {
11358 for (i = 0; i < req->n_channels ; i++ )
11359 {
11360 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11361 }
11362 /* store no of channel scanned */
11363 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11364 }
11365
11366 }
11367
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011368 /*
11369 * cfg80211_scan_done informing NL80211 about completion
11370 * of scanning
11371 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011372 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11373 {
11374 aborted = true;
11375 }
11376 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011377 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011378
Siddharth Bhal76972212014-10-15 16:22:51 +053011379 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11380 /* Generate new random mac addr for next scan */
11381 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11382 hdd_processSpoofMacAddrRequest(pHddCtx);
11383 }
11384
Jeff Johnsone7245742012-09-05 17:12:55 -070011385allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011386 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011387 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011388
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011389 /* Acquire wakelock to handle the case where APP's tries to suspend
11390 * immediatly after the driver gets connect request(i.e after scan)
11391 * from supplicant, this result in app's is suspending and not able
11392 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011393 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011394
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011395#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011396 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011397#endif
11398
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 EXIT();
11400 return 0;
11401}
11402
11403/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011404 * FUNCTION: hdd_isConnectionInProgress
11405 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011406 *
11407 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011408v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011409{
11410 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11411 hdd_station_ctx_t *pHddStaCtx = NULL;
11412 hdd_adapter_t *pAdapter = NULL;
11413 VOS_STATUS status = 0;
11414 v_U8_t staId = 0;
11415 v_U8_t *staMac = NULL;
11416
c_hpothu9b781ba2013-12-30 20:57:45 +053011417 if (TRUE == pHddCtx->btCoexModeSet)
11418 {
11419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011420 FL("BTCoex Mode operation in progress"));
11421 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011422 }
11423
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011424 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11425
11426 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11427 {
11428 pAdapter = pAdapterNode->pAdapter;
11429
11430 if( pAdapter )
11431 {
11432 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011433 "%s: Adapter with device mode %s (%d) exists",
11434 __func__, hdd_device_modetoString(pAdapter->device_mode),
11435 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011436 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011437 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11438 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11439 (eConnectionState_Connecting ==
11440 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11441 {
11442 hddLog(VOS_TRACE_LEVEL_ERROR,
11443 "%s: %p(%d) Connection is in progress", __func__,
11444 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11445 return VOS_TRUE;
11446 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011447 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011448 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011449 {
11450 hddLog(VOS_TRACE_LEVEL_ERROR,
11451 "%s: %p(%d) Reassociation is in progress", __func__,
11452 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11453 return VOS_TRUE;
11454 }
11455 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011456 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11457 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011458 {
11459 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11460 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011461 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011462 {
11463 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11464 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011465 "%s: client " MAC_ADDRESS_STR
11466 " is in the middle of WPS/EAPOL exchange.", __func__,
11467 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011468 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011469 }
11470 }
11471 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11472 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11473 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011474 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11475 ptSapContext pSapCtx = NULL;
11476 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11477 if(pSapCtx == NULL){
11478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11479 FL("psapCtx is NULL"));
11480 return VOS_FALSE;
11481 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011482 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11483 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011484 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11485 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011486 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011487 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011488
11489 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011490 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11491 "middle of WPS/EAPOL exchange.", __func__,
11492 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011493 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011494 }
11495 }
11496 }
11497 }
11498 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11499 pAdapterNode = pNext;
11500 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011501 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011502}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011503
11504/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011505 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 * this scan respond to scan trigger and update cfg80211 scan database
11507 * later, scan dump command can be used to recieve scan results
11508 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011509int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011510#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11511 struct net_device *dev,
11512#endif
11513 struct cfg80211_scan_request *request)
11514{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011515 hdd_adapter_t *pAdapter = NULL;
11516 hdd_context_t *pHddCtx = NULL;
11517 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011518 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 tCsrScanRequest scanRequest;
11520 tANI_U8 *channelList = NULL, i;
11521 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011522 int status;
11523 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011525 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011526 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011527 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011528 v_S7_t rssi=0;
11529 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011530
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11532 struct net_device *dev = NULL;
11533 if (NULL == request)
11534 {
11535 hddLog(VOS_TRACE_LEVEL_ERROR,
11536 "%s: scan req param null", __func__);
11537 return -EINVAL;
11538 }
11539 dev = request->wdev->netdev;
11540#endif
11541
11542 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11543 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11544 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11545
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 ENTER();
11547
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11549 __func__, hdd_device_modetoString(pAdapter->device_mode),
11550 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011552 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011553 if (0 != status)
11554 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011555 return status;
11556 }
11557
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011558 if (NULL == pwextBuf)
11559 {
11560 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11561 __func__);
11562 return -EIO;
11563 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011564 cfg_param = pHddCtx->cfg_ini;
11565 pScanInfo = &pHddCtx->scan_info;
11566
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011567 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11568 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11569 {
11570 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11571 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11572 }
11573
Jeff Johnson295189b2012-06-20 16:38:30 -070011574#ifdef WLAN_BTAMP_FEATURE
11575 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011576 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011578 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 "%s: No scanning when AMP is on", __func__);
11580 return -EOPNOTSUPP;
11581 }
11582#endif
11583 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011584 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011586 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011587 "%s: Not scanning on device_mode = %s (%d)",
11588 __func__, hdd_device_modetoString(pAdapter->device_mode),
11589 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 return -EOPNOTSUPP;
11591 }
11592
11593 if (TRUE == pScanInfo->mScanPending)
11594 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011595 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11596 {
11597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11598 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011599 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 }
11601
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011602 // Don't allow scan if PNO scan is going on.
11603 if (pHddCtx->isPnoEnable)
11604 {
11605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11606 FL("pno scan in progress"));
11607 return -EBUSY;
11608 }
11609
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011610 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011611 //Channel and action frame is pending
11612 //Otherwise Cancel Remain On Channel and allow Scan
11613 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011614 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011615 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011617 return -EBUSY;
11618 }
11619
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11621 {
11622 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011623 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011624 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011625 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11627 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011628 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 "%s: MAX TM Level Scan not allowed", __func__);
11630 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011631 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011632 }
11633 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11634
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011635 /* Check if scan is allowed at this point of time.
11636 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011637 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011638 {
11639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11640 return -EBUSY;
11641 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11644
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011645 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11646 * Becasue of this, driver is assuming that this is not wildcard scan and so
11647 * is not aging out the scan results.
11648 */
11649 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011651 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011653
11654 if ((request->ssids) && (0 < request->n_ssids))
11655 {
11656 tCsrSSIDInfo *SsidInfo;
11657 int j;
11658 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11659 /* Allocate num_ssid tCsrSSIDInfo structure */
11660 SsidInfo = scanRequest.SSIDs.SSIDList =
11661 ( tCsrSSIDInfo *)vos_mem_malloc(
11662 request->n_ssids*sizeof(tCsrSSIDInfo));
11663
11664 if(NULL == scanRequest.SSIDs.SSIDList)
11665 {
11666 hddLog(VOS_TRACE_LEVEL_ERROR,
11667 "%s: memory alloc failed SSIDInfo buffer", __func__);
11668 return -ENOMEM;
11669 }
11670
11671 /* copy all the ssid's and their length */
11672 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11673 {
11674 /* get the ssid length */
11675 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11676 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11677 SsidInfo->SSID.length);
11678 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11679 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11680 j, SsidInfo->SSID.ssId);
11681 }
11682 /* set the scan type to active */
11683 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11684 }
11685 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011687 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11688 TRACE_CODE_HDD_CFG80211_SCAN,
11689 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 /* set the scan type to active */
11691 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011693 else
11694 {
11695 /*Set the scan type to default type, in this case it is ACTIVE*/
11696 scanRequest.scanType = pScanInfo->scan_mode;
11697 }
11698 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11699 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011700
11701 /* set BSSType to default type */
11702 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11703
11704 /*TODO: scan the requested channels only*/
11705
11706 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011707 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011709 hddLog(VOS_TRACE_LEVEL_WARN,
11710 "No of Scan Channels exceeded limit: %d", request->n_channels);
11711 request->n_channels = MAX_CHANNEL;
11712 }
11713
11714 hddLog(VOS_TRACE_LEVEL_INFO,
11715 "No of Scan Channels: %d", request->n_channels);
11716
11717
11718 if( request->n_channels )
11719 {
11720 char chList [(request->n_channels*5)+1];
11721 int len;
11722 channelList = vos_mem_malloc( request->n_channels );
11723 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011724 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011725 hddLog(VOS_TRACE_LEVEL_ERROR,
11726 "%s: memory alloc failed channelList", __func__);
11727 status = -ENOMEM;
11728 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011729 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011730
11731 for( i = 0, len = 0; i < request->n_channels ; i++ )
11732 {
11733 channelList[i] = request->channels[i]->hw_value;
11734 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11735 }
11736
Nirav Shah20ac06f2013-12-12 18:14:06 +053011737 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011738 "Channel-List: %s ", chList);
11739 }
c_hpothu53512302014-04-15 18:49:53 +053011740
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011741 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11742 scanRequest.ChannelInfo.ChannelList = channelList;
11743
11744 /* set requestType to full scan */
11745 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11746
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011747 /* if there is back to back scan happening in driver with in
11748 * nDeferScanTimeInterval interval driver should defer new scan request
11749 * and should provide last cached scan results instead of new channel list.
11750 * This rule is not applicable if scan is p2p scan.
11751 * This condition will work only in case when last request no of channels
11752 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011753 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011754 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011755 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011756
Sushant Kaushik86592172015-04-27 16:35:03 +053011757 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11758 /* if wps ie is NULL , then only defer scan */
11759 if ( pWpsIe == NULL &&
11760 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011761 {
11762 if ( pScanInfo->last_scan_timestamp !=0 &&
11763 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11764 {
11765 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11766 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11767 vos_mem_compare(pScanInfo->last_scan_channelList,
11768 channelList, pScanInfo->last_scan_numChannels))
11769 {
11770 hddLog(VOS_TRACE_LEVEL_WARN,
11771 " New and old station scan time differ is less then %u",
11772 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11773
11774 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011775 pAdapter);
11776
Agarwal Ashish57e84372014-12-05 18:26:53 +053011777 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011778 "Return old cached scan as all channels and no of channels are same");
11779
Agarwal Ashish57e84372014-12-05 18:26:53 +053011780 if (0 > ret)
11781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011782
Agarwal Ashish57e84372014-12-05 18:26:53 +053011783 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011784
11785 status = eHAL_STATUS_SUCCESS;
11786 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011787 }
11788 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011789 }
11790
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011791 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11792 * search (Flush on both full scan and social scan but not on single
11793 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11794 */
11795
11796 /* Supplicant does single channel scan after 8-way handshake
11797 * and in that case driver shoudnt flush scan results. If
11798 * driver flushes the scan results here and unfortunately if
11799 * the AP doesnt respond to our probe req then association
11800 * fails which is not desired
11801 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011802 if ((request->n_ssids == 1)
11803 && (request->ssids != NULL)
11804 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11805 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011806
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011807 if( is_p2p_scan ||
11808 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011809 {
11810 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11811 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11812 pAdapter->sessionId );
11813 }
11814
11815 if( request->ie_len )
11816 {
11817 /* save this for future association (join requires this) */
11818 /*TODO: Array needs to be converted to dynamic allocation,
11819 * as multiple ie.s can be sent in cfg80211_scan_request structure
11820 * CR 597966
11821 */
11822 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11823 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11824 pScanInfo->scanAddIE.length = request->ie_len;
11825
11826 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11827 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11828 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011830 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011832 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11833 memcpy( pwextBuf->roamProfile.addIEScan,
11834 request->ie, request->ie_len);
11835 }
11836 else
11837 {
11838 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11839 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 }
11841
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011842 }
11843 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11844 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11845
11846 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11847 request->ie_len);
11848 if (pP2pIe != NULL)
11849 {
11850#ifdef WLAN_FEATURE_P2P_DEBUG
11851 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11852 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11853 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011854 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011855 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11856 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11857 "Go nego completed to Connection is started");
11858 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11859 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011860 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011861 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11862 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011864 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11865 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11866 "Disconnected state to Connection is started");
11867 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11868 "for 4way Handshake");
11869 }
11870#endif
11871
11872 /* no_cck will be set during p2p find to disable 11b rates */
11873 if(TRUE == request->no_cck)
11874 {
11875 hddLog(VOS_TRACE_LEVEL_INFO,
11876 "%s: This is a P2P Search", __func__);
11877 scanRequest.p2pSearch = 1;
11878
11879 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011880 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011881 /* set requestType to P2P Discovery */
11882 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11883 }
11884
11885 /*
11886 Skip Dfs Channel in case of P2P Search
11887 if it is set in ini file
11888 */
11889 if(cfg_param->skipDfsChnlInP2pSearch)
11890 {
11891 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011892 }
11893 else
11894 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011895 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011897
Agarwal Ashish4f616132013-12-30 23:32:50 +053011898 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 }
11900 }
11901
11902 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11903
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011904#ifdef FEATURE_WLAN_TDLS
11905 /* if tdls disagree scan right now, return immediately.
11906 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11907 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11908 */
11909 status = wlan_hdd_tdls_scan_callback (pAdapter,
11910 wiphy,
11911#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11912 dev,
11913#endif
11914 request);
11915 if(status <= 0)
11916 {
11917 if(!status)
11918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11919 "scan rejected %d", __func__, status);
11920 else
11921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11922 __func__, status);
11923
11924 return status;
11925 }
11926#endif
11927
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011928 /* acquire the wakelock to avoid the apps suspend during the scan. To
11929 * address the following issues.
11930 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11931 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11932 * for long time, this result in apps running at full power for long time.
11933 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11934 * be stuck in full power because of resume BMPS
11935 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011936 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011937
Nirav Shah20ac06f2013-12-12 18:14:06 +053011938 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11939 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011940 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11941 scanRequest.requestType, scanRequest.scanType,
11942 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011943 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11944
Siddharth Bhal76972212014-10-15 16:22:51 +053011945 if (pHddCtx->spoofMacAddr.isEnabled)
11946 {
11947 hddLog(VOS_TRACE_LEVEL_INFO,
11948 "%s: MAC Spoofing enabled for current scan", __func__);
11949 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11950 * to fill TxBds for probe request during current scan
11951 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011952 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011953 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011954
11955 if(status != VOS_STATUS_SUCCESS)
11956 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011957 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011958 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011959#ifdef FEATURE_WLAN_TDLS
11960 wlan_hdd_tdls_scan_done_callback(pAdapter);
11961#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011962 goto free_mem;
11963 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011964 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011965 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011966 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 pAdapter->sessionId, &scanRequest, &scanId,
11968 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011969
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 if (eHAL_STATUS_SUCCESS != status)
11971 {
11972 hddLog(VOS_TRACE_LEVEL_ERROR,
11973 "%s: sme_ScanRequest returned error %d", __func__, status);
11974 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011975 if(eHAL_STATUS_RESOURCES == status)
11976 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11978 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011979 status = -EBUSY;
11980 } else {
11981 status = -EIO;
11982 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011983 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011984
11985#ifdef FEATURE_WLAN_TDLS
11986 wlan_hdd_tdls_scan_done_callback(pAdapter);
11987#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 goto free_mem;
11989 }
11990
11991 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011992 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 pAdapter->request = request;
11994 pScanInfo->scanId = scanId;
11995
11996 complete(&pScanInfo->scan_req_completion_event);
11997
11998free_mem:
11999 if( scanRequest.SSIDs.SSIDList )
12000 {
12001 vos_mem_free(scanRequest.SSIDs.SSIDList);
12002 }
12003
12004 if( channelList )
12005 vos_mem_free( channelList );
12006
12007 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 return status;
12009}
12010
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012011int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
12012#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12013 struct net_device *dev,
12014#endif
12015 struct cfg80211_scan_request *request)
12016{
12017 int ret;
12018
12019 vos_ssr_protect(__func__);
12020 ret = __wlan_hdd_cfg80211_scan(wiphy,
12021#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12022 dev,
12023#endif
12024 request);
12025 vos_ssr_unprotect(__func__);
12026
12027 return ret;
12028}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012029
12030void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
12031{
12032 v_U8_t iniDot11Mode =
12033 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
12034 eHddDot11Mode hddDot11Mode = iniDot11Mode;
12035
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012036 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
12037 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012038 switch ( iniDot11Mode )
12039 {
12040 case eHDD_DOT11_MODE_AUTO:
12041 case eHDD_DOT11_MODE_11ac:
12042 case eHDD_DOT11_MODE_11ac_ONLY:
12043#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053012044 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
12045 sme_IsFeatureSupportedByFW(DOT11AC) )
12046 hddDot11Mode = eHDD_DOT11_MODE_11ac;
12047 else
12048 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012049#else
12050 hddDot11Mode = eHDD_DOT11_MODE_11n;
12051#endif
12052 break;
12053 case eHDD_DOT11_MODE_11n:
12054 case eHDD_DOT11_MODE_11n_ONLY:
12055 hddDot11Mode = eHDD_DOT11_MODE_11n;
12056 break;
12057 default:
12058 hddDot11Mode = iniDot11Mode;
12059 break;
12060 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053012061#ifdef WLAN_FEATURE_AP_HT40_24G
12062 if (operationChannel > SIR_11B_CHANNEL_END)
12063#endif
12064 {
12065 /* This call decides required channel bonding mode */
12066 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012067 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
12068 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053012069 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012070}
12071
Jeff Johnson295189b2012-06-20 16:38:30 -070012072/*
12073 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012074 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012077 const u8 *ssid, size_t ssid_len, const u8 *bssid,
12078 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070012079{
12080 int status = 0;
12081 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080012082 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 v_U32_t roamId;
12084 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070012085 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012086 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012087
12088 ENTER();
12089
12090 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080012091 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12092
12093 status = wlan_hdd_validate_context(pHddCtx);
12094 if (status)
12095 {
Yue Mae36e3552014-03-05 17:06:20 -080012096 return status;
12097 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
12100 {
12101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
12102 return -EINVAL;
12103 }
12104
12105 pRoamProfile = &pWextState->roamProfile;
12106
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012107 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070012108 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012109 hdd_station_ctx_t *pHddStaCtx;
12110 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012111
Siddharth Bhalda0d1622015-04-24 15:47:49 +053012112 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
12113
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012114 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
12116 {
12117 /*QoS not enabled in cfg file*/
12118 pRoamProfile->uapsd_mask = 0;
12119 }
12120 else
12121 {
12122 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012123 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
12125 }
12126
12127 pRoamProfile->SSIDs.numOfSSIDs = 1;
12128 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
12129 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012130 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
12132 ssid, ssid_len);
12133
12134 if (bssid)
12135 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012136 pValidBssid = bssid;
12137 }
12138 else if (bssid_hint)
12139 {
12140 pValidBssid = bssid_hint;
12141 }
12142 if (pValidBssid)
12143 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012145 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012146 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012147 /* Save BSSID in seperate variable as well, as RoamProfile
12148 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 case of join failure we should send valid BSSID to supplicant
12150 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012151 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 WNI_CFG_BSSID_LEN);
12153 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070012154 else
12155 {
12156 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
12157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012158
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012159 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
12160 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
12162 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 /*set gen ie*/
12165 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
12166 /*set auth*/
12167 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
12168 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012169#ifdef FEATURE_WLAN_WAPI
12170 if (pAdapter->wapi_info.nWapiMode)
12171 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012172 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 switch (pAdapter->wapi_info.wapiAuthMode)
12174 {
12175 case WAPI_AUTH_MODE_PSK:
12176 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012177 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 pAdapter->wapi_info.wapiAuthMode);
12179 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
12180 break;
12181 }
12182 case WAPI_AUTH_MODE_CERT:
12183 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012184 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 pAdapter->wapi_info.wapiAuthMode);
12186 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
12187 break;
12188 }
12189 } // End of switch
12190 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
12191 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
12192 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012193 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 pRoamProfile->AuthType.numEntries = 1;
12195 pRoamProfile->EncryptionType.numEntries = 1;
12196 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12197 pRoamProfile->mcEncryptionType.numEntries = 1;
12198 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12199 }
12200 }
12201#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012202#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012203 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012204 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12205 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
12206 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012207 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
12208 sizeof (tSirGtkOffloadParams));
12209 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012210 }
12211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 pRoamProfile->csrPersona = pAdapter->device_mode;
12213
Jeff Johnson32d95a32012-09-10 13:15:23 -070012214 if( operatingChannel )
12215 {
12216 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
12217 pRoamProfile->ChannelInfo.numOfChannels = 1;
12218 }
Chet Lanctot186b5732013-03-18 10:26:30 -070012219 else
12220 {
12221 pRoamProfile->ChannelInfo.ChannelList = NULL;
12222 pRoamProfile->ChannelInfo.numOfChannels = 0;
12223 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012224 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
12225 {
12226 hdd_select_cbmode(pAdapter,operatingChannel);
12227 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012228
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012229 /*
12230 * Change conn_state to connecting before sme_RoamConnect(),
12231 * because sme_RoamConnect() has a direct path to call
12232 * hdd_smeRoamCallback(), which will change the conn_state
12233 * If direct path, conn_state will be accordingly changed
12234 * to NotConnected or Associated by either
12235 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
12236 * in sme_RoamCallback()
12237 * if sme_RomConnect is to be queued,
12238 * Connecting state will remain until it is completed.
12239 * If connection state is not changed,
12240 * connection state will remain in eConnectionState_NotConnected state.
12241 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12242 * if conn state is eConnectionState_NotConnected.
12243 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12244 * informed of connect result indication which is an issue.
12245 */
12246
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012247 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12248 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012249 {
12250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012251 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012252 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12253 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 pAdapter->sessionId, pRoamProfile, &roamId);
12257
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012258 if ((eHAL_STATUS_SUCCESS != status) &&
12259 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12260 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012261
12262 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012263 hddLog(VOS_TRACE_LEVEL_ERROR,
12264 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12265 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012266 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012267 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012268 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012269 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012270
12271 pRoamProfile->ChannelInfo.ChannelList = NULL;
12272 pRoamProfile->ChannelInfo.numOfChannels = 0;
12273
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 }
12275 else
12276 {
12277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12278 return -EINVAL;
12279 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012280 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 return status;
12282}
12283
12284/*
12285 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12286 * This function is used to set the authentication type (OPEN/SHARED).
12287 *
12288 */
12289static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12290 enum nl80211_auth_type auth_type)
12291{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012292 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12294
12295 ENTER();
12296
12297 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012298 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012301 hddLog(VOS_TRACE_LEVEL_INFO,
12302 "%s: set authentication type to AUTOSWITCH", __func__);
12303 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12304 break;
12305
12306 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012307#ifdef WLAN_FEATURE_VOWIFI_11R
12308 case NL80211_AUTHTYPE_FT:
12309#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012310 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 "%s: set authentication type to OPEN", __func__);
12312 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12313 break;
12314
12315 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 "%s: set authentication type to SHARED", __func__);
12318 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12319 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012320#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012322 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012323 "%s: set authentication type to CCKM WPA", __func__);
12324 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12325 break;
12326#endif
12327
12328
12329 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012330 hddLog(VOS_TRACE_LEVEL_ERROR,
12331 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 auth_type);
12333 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12334 return -EINVAL;
12335 }
12336
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012337 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 pHddStaCtx->conn_info.authType;
12339 return 0;
12340}
12341
12342/*
12343 * FUNCTION: wlan_hdd_set_akm_suite
12344 * This function is used to set the key mgmt type(PSK/8021x).
12345 *
12346 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012347static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 u32 key_mgmt
12349 )
12350{
12351 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12352 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012353 /* Should be in ieee802_11_defs.h */
12354#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12355#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 /*set key mgmt type*/
12357 switch(key_mgmt)
12358 {
12359 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012360 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012361#ifdef WLAN_FEATURE_VOWIFI_11R
12362 case WLAN_AKM_SUITE_FT_PSK:
12363#endif
12364 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 __func__);
12366 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12367 break;
12368
12369 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012370 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012371#ifdef WLAN_FEATURE_VOWIFI_11R
12372 case WLAN_AKM_SUITE_FT_8021X:
12373#endif
12374 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 __func__);
12376 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12377 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012378#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012379#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12380#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12381 case WLAN_AKM_SUITE_CCKM:
12382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12383 __func__);
12384 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12385 break;
12386#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012387#ifndef WLAN_AKM_SUITE_OSEN
12388#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12389 case WLAN_AKM_SUITE_OSEN:
12390 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12391 __func__);
12392 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12393 break;
12394#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012395
12396 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 __func__, key_mgmt);
12399 return -EINVAL;
12400
12401 }
12402 return 0;
12403}
12404
12405/*
12406 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012407 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 * (NONE/WEP40/WEP104/TKIP/CCMP).
12409 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012410static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12411 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 bool ucast
12413 )
12414{
12415 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012416 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012417 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12418
12419 ENTER();
12420
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012421 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012423 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 __func__, cipher);
12425 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12426 }
12427 else
12428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012429
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012431 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 {
12433 case IW_AUTH_CIPHER_NONE:
12434 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12435 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012436
Jeff Johnson295189b2012-06-20 16:38:30 -070012437 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012438 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012440
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012442 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012444
Jeff Johnson295189b2012-06-20 16:38:30 -070012445 case WLAN_CIPHER_SUITE_TKIP:
12446 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12447 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012448
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 case WLAN_CIPHER_SUITE_CCMP:
12450 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12451 break;
12452#ifdef FEATURE_WLAN_WAPI
12453 case WLAN_CIPHER_SUITE_SMS4:
12454 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12455 break;
12456#endif
12457
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012458#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012459 case WLAN_CIPHER_SUITE_KRK:
12460 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12461 break;
12462#endif
12463 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 __func__, cipher);
12466 return -EOPNOTSUPP;
12467 }
12468 }
12469
12470 if (ucast)
12471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 __func__, encryptionType);
12474 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12475 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012476 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012477 encryptionType;
12478 }
12479 else
12480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012482 __func__, encryptionType);
12483 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12484 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12485 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12486 }
12487
12488 return 0;
12489}
12490
12491
12492/*
12493 * FUNCTION: wlan_hdd_cfg80211_set_ie
12494 * This function is used to parse WPA/RSN IE's.
12495 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012496int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012497#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12498 const u8 *ie,
12499#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012500 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 size_t ie_len
12503 )
12504{
12505 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12507 const u8 *genie = ie;
12508#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012509 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012510#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 v_U16_t remLen = ie_len;
12512#ifdef FEATURE_WLAN_WAPI
12513 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12514 u16 *tmp;
12515 v_U16_t akmsuiteCount;
12516 int *akmlist;
12517#endif
12518 ENTER();
12519
12520 /* clear previous assocAddIE */
12521 pWextState->assocAddIE.length = 0;
12522 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012523 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012524
12525 while (remLen >= 2)
12526 {
12527 v_U16_t eLen = 0;
12528 v_U8_t elementId;
12529 elementId = *genie++;
12530 eLen = *genie++;
12531 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012532
Arif Hussain6d2a3322013-11-17 19:50:10 -080012533 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012534 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012535
12536 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012538 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012539 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 -070012540 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012541 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 "%s: Invalid WPA IE", __func__);
12543 return -EINVAL;
12544 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012545 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 {
12547 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012548 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012550
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012551 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012553 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12554 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 VOS_ASSERT(0);
12556 return -ENOMEM;
12557 }
12558 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12559 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12560 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012561
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12563 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12564 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12565 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012566 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12567 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12569 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12570 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12571 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12572 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12573 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012574 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012575 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012576 {
12577 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012578 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012579 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012580
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012581 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012582 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012583 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12584 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 VOS_ASSERT(0);
12586 return -ENOMEM;
12587 }
12588 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12589 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12590 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012591
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12593 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12594 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012595#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012596 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12597 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 /*Consider WFD IE, only for P2P Client */
12599 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12600 {
12601 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012602 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012604
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012605 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012607 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12608 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 VOS_ASSERT(0);
12610 return -ENOMEM;
12611 }
12612 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12613 // WPS IE + P2P IE + WFD IE
12614 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12615 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012616
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12618 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12619 }
12620#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012621 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012622 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012623 HS20_OUI_TYPE_SIZE)) )
12624 {
12625 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012627 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012628
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012629 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012630 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012631 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12632 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012633 VOS_ASSERT(0);
12634 return -ENOMEM;
12635 }
12636 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12637 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012638
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012639 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12640 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12641 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012642 /* Appending OSEN Information Element in Assiciation Request */
12643 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12644 OSEN_OUI_TYPE_SIZE)) )
12645 {
12646 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12647 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12648 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012649
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012650 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012651 {
12652 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12653 "Need bigger buffer space");
12654 VOS_ASSERT(0);
12655 return -ENOMEM;
12656 }
12657 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12658 pWextState->assocAddIE.length += eLen + 2;
12659
12660 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12661 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12662 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12663 }
12664
Abhishek Singh4322e622015-06-10 15:42:54 +053012665 /* Update only for WPA IE */
12666 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12667 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012668
12669 /* populating as ADDIE in beacon frames */
12670 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012671 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012672 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12673 {
12674 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12675 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12676 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12677 {
12678 hddLog(LOGE,
12679 "Coldn't pass "
12680 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12681 }
12682 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12683 else
12684 hddLog(LOGE,
12685 "Could not pass on "
12686 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12687
12688 /* IBSS mode doesn't contain params->proberesp_ies still
12689 beaconIE's need to be populated in probe response frames */
12690 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12691 {
12692 u16 rem_probe_resp_ie_len = eLen + 2;
12693 u8 probe_rsp_ie_len[3] = {0};
12694 u8 counter = 0;
12695
12696 /* Check Probe Resp Length if it is greater then 255 then
12697 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12698 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12699 not able Store More then 255 bytes into One Variable */
12700
12701 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12702 {
12703 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12704 {
12705 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12706 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12707 }
12708 else
12709 {
12710 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12711 rem_probe_resp_ie_len = 0;
12712 }
12713 }
12714
12715 rem_probe_resp_ie_len = 0;
12716
12717 if (probe_rsp_ie_len[0] > 0)
12718 {
12719 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12720 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12721 (tANI_U8*)(genie - 2),
12722 probe_rsp_ie_len[0], NULL,
12723 eANI_BOOLEAN_FALSE)
12724 == eHAL_STATUS_FAILURE)
12725 {
12726 hddLog(LOGE,
12727 "Could not pass"
12728 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12729 }
12730 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12731 }
12732
12733 if (probe_rsp_ie_len[1] > 0)
12734 {
12735 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12736 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12737 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12738 probe_rsp_ie_len[1], NULL,
12739 eANI_BOOLEAN_FALSE)
12740 == eHAL_STATUS_FAILURE)
12741 {
12742 hddLog(LOGE,
12743 "Could not pass"
12744 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12745 }
12746 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12747 }
12748
12749 if (probe_rsp_ie_len[2] > 0)
12750 {
12751 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12752 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12753 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12754 probe_rsp_ie_len[2], NULL,
12755 eANI_BOOLEAN_FALSE)
12756 == eHAL_STATUS_FAILURE)
12757 {
12758 hddLog(LOGE,
12759 "Could not pass"
12760 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12761 }
12762 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12763 }
12764
12765 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12766 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12767 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12768 {
12769 hddLog(LOGE,
12770 "Could not pass"
12771 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12772 }
12773 }
12774 else
12775 {
12776 // Reset WNI_CFG_PROBE_RSP Flags
12777 wlan_hdd_reset_prob_rspies(pAdapter);
12778
12779 hddLog(VOS_TRACE_LEVEL_INFO,
12780 "%s: No Probe Response IE received in set beacon",
12781 __func__);
12782 }
12783 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012784 break;
12785 case DOT11F_EID_RSN:
12786 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12787 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12788 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12789 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12790 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12791 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012792
12793 /* Appending Extended Capabilities with Interworking bit set
12794 * in Assoc Req.
12795 *
12796 * In assoc req this EXT Cap will only be taken into account if
12797 * interworkingService bit is set to 1. Currently
12798 * driver is only interested in interworkingService capability
12799 * from supplicant. If in future any other EXT Cap info is
12800 * required from supplicat, it needs to be handled while
12801 * sending Assoc Req in LIM.
12802 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012803 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012804 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012805 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012806 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012807 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012808
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012809 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012810 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012811 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12812 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012813 VOS_ASSERT(0);
12814 return -ENOMEM;
12815 }
12816 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12817 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012819 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12820 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12821 break;
12822 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012823#ifdef FEATURE_WLAN_WAPI
12824 case WLAN_EID_WAPI:
12825 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012826 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012827 pAdapter->wapi_info.nWapiMode);
12828 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012829 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 akmsuiteCount = WPA_GET_LE16(tmp);
12831 tmp = tmp + 1;
12832 akmlist = (int *)(tmp);
12833 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12834 {
12835 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12836 }
12837 else
12838 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012839 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 VOS_ASSERT(0);
12841 return -EINVAL;
12842 }
12843
12844 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12845 {
12846 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012847 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012851 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012852 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012853 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12855 }
12856 break;
12857#endif
12858 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012859 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012860 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012861 /* when Unknown IE is received we should break and continue
12862 * to the next IE in the buffer instead we were returning
12863 * so changing this to break */
12864 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 }
12866 genie += eLen;
12867 remLen -= eLen;
12868 }
12869 EXIT();
12870 return 0;
12871}
12872
12873/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012874 * FUNCTION: hdd_isWPAIEPresent
12875 * Parse the received IE to find the WPA IE
12876 *
12877 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012878static bool hdd_isWPAIEPresent(
12879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12880 const u8 *ie,
12881#else
12882 u8 *ie,
12883#endif
12884 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012885{
12886 v_U8_t eLen = 0;
12887 v_U16_t remLen = ie_len;
12888 v_U8_t elementId = 0;
12889
12890 while (remLen >= 2)
12891 {
12892 elementId = *ie++;
12893 eLen = *ie++;
12894 remLen -= 2;
12895 if (eLen > remLen)
12896 {
12897 hddLog(VOS_TRACE_LEVEL_ERROR,
12898 "%s: IE length is wrong %d", __func__, eLen);
12899 return FALSE;
12900 }
12901 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12902 {
12903 /* OUI - 0x00 0X50 0XF2
12904 WPA Information Element - 0x01
12905 WPA version - 0x01*/
12906 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12907 return TRUE;
12908 }
12909 ie += eLen;
12910 remLen -= eLen;
12911 }
12912 return FALSE;
12913}
12914
12915/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012917 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 * parameters during connect operation.
12919 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012920int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012922 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012923{
12924 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012925 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 ENTER();
12927
12928 /*set wpa version*/
12929 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12930
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012931 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012932 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012933 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012934 {
12935 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12936 }
12937 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12938 {
12939 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12940 }
12941 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012942
12943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 pWextState->wpaVersion);
12945
12946 /*set authentication type*/
12947 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12948
12949 if (0 > status)
12950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012951 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012952 "%s: failed to set authentication type ", __func__);
12953 return status;
12954 }
12955
12956 /*set key mgmt type*/
12957 if (req->crypto.n_akm_suites)
12958 {
12959 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12960 if (0 > status)
12961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012963 __func__);
12964 return status;
12965 }
12966 }
12967
12968 /*set pairwise cipher type*/
12969 if (req->crypto.n_ciphers_pairwise)
12970 {
12971 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12972 req->crypto.ciphers_pairwise[0], true);
12973 if (0 > status)
12974 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012975 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012976 "%s: failed to set unicast cipher type", __func__);
12977 return status;
12978 }
12979 }
12980 else
12981 {
12982 /*Reset previous cipher suite to none*/
12983 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12984 if (0 > status)
12985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012986 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012987 "%s: failed to set unicast cipher type", __func__);
12988 return status;
12989 }
12990 }
12991
12992 /*set group cipher type*/
12993 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12994 false);
12995
12996 if (0 > status)
12997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012998 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 __func__);
13000 return status;
13001 }
13002
Chet Lanctot186b5732013-03-18 10:26:30 -070013003#ifdef WLAN_FEATURE_11W
13004 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
13005#endif
13006
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
13008 if (req->ie_len)
13009 {
13010 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
13011 if ( 0 > status)
13012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 __func__);
13015 return status;
13016 }
13017 }
13018
13019 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013020 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 {
13022 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
13023 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
13024 )
13025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013026 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070013027 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
13028 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013029 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013030 __func__);
13031 return -EOPNOTSUPP;
13032 }
13033 else
13034 {
13035 u8 key_len = req->key_len;
13036 u8 key_idx = req->key_idx;
13037
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013038 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 && (CSR_MAX_NUM_KEY > key_idx)
13040 )
13041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013042 hddLog(VOS_TRACE_LEVEL_INFO,
13043 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 __func__, key_idx, key_len);
13045 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013046 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013048 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 (u8)key_len;
13050 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
13051 }
13052 }
13053 }
13054 }
13055
13056 return status;
13057}
13058
13059/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013060 * FUNCTION: wlan_hdd_try_disconnect
13061 * This function is used to disconnect from previous
13062 * connection
13063 */
13064static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
13065{
13066 long ret = 0;
13067 hdd_station_ctx_t *pHddStaCtx;
13068 eMib_dot11DesiredBssType connectedBssType;
13069
13070 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13071
13072 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
13073
13074 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
13075 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
13076 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
13077 {
13078 /* Issue disconnect to CSR */
13079 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13080 if( eHAL_STATUS_SUCCESS ==
13081 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13082 pAdapter->sessionId,
13083 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
13084 {
13085 ret = wait_for_completion_interruptible_timeout(
13086 &pAdapter->disconnect_comp_var,
13087 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
13088 if (0 >= ret)
13089 {
13090 hddLog(LOGE, FL("Failed to receive disconnect event"));
13091 return -EALREADY;
13092 }
13093 }
13094 }
13095 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
13096 {
13097 ret = wait_for_completion_interruptible_timeout(
13098 &pAdapter->disconnect_comp_var,
13099 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
13100 if (0 >= ret)
13101 {
13102 hddLog(LOGE, FL("Failed to receive disconnect event"));
13103 return -EALREADY;
13104 }
13105 }
13106
13107 return 0;
13108}
13109
13110/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053013111 * FUNCTION: __wlan_hdd_cfg80211_connect
13112 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013113 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013114static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 struct net_device *ndev,
13116 struct cfg80211_connect_params *req
13117 )
13118{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013119 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013120 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013121 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053013122 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013123
13124 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013126 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13127 TRACE_CODE_HDD_CFG80211_CONNECT,
13128 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013129 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013130 "%s: device_mode = %s (%d)", __func__,
13131 hdd_device_modetoString(pAdapter->device_mode),
13132 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013133
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013134 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013135 if (!pHddCtx)
13136 {
13137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13138 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013139 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013140 }
13141
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013142 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013143 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013144 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013145 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013146 }
13147
Agarwal Ashish51325b52014-06-16 16:50:49 +053013148 if (vos_max_concurrent_connections_reached()) {
13149 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13150 return -ECONNREFUSED;
13151 }
13152
Jeff Johnson295189b2012-06-20 16:38:30 -070013153#ifdef WLAN_BTAMP_FEATURE
13154 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013155 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070013156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013157 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013158 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013159 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 }
13161#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013162
13163 //If Device Mode is Station Concurrent Sessions Exit BMps
13164 //P2P Mode will be taken care in Open/close adapter
13165 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053013166 (vos_concurrent_open_sessions_running())) {
13167 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
13168 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013169 }
13170
13171 /*Try disconnecting if already in connected state*/
13172 status = wlan_hdd_try_disconnect(pAdapter);
13173 if ( 0 > status)
13174 {
13175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13176 " connection"));
13177 return -EALREADY;
13178 }
13179
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013181 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070013182
13183 if ( 0 > status)
13184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070013186 __func__);
13187 return status;
13188 }
Mohit Khanna765234a2012-09-11 15:08:35 -070013189 if ( req->channel )
13190 {
13191 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
13192 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013193 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070013194 req->channel->hw_value);
13195 }
13196 else
13197 {
13198 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013199 req->ssid_len, req->bssid,
13200 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070013201 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013202
Sushant Kaushikd7083982015-03-18 14:33:24 +053013203 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013204 {
13205 //ReEnable BMPS if disabled
13206 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
13207 (NULL != pHddCtx))
13208 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053013209 if (pHddCtx->hdd_wlan_suspended)
13210 {
13211 hdd_set_pwrparams(pHddCtx);
13212 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 //ReEnable Bmps and Imps back
13214 hdd_enable_bmps_imps(pHddCtx);
13215 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070013217 return status;
13218 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013219 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013220 EXIT();
13221 return status;
13222}
13223
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013224static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
13225 struct net_device *ndev,
13226 struct cfg80211_connect_params *req)
13227{
13228 int ret;
13229 vos_ssr_protect(__func__);
13230 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
13231 vos_ssr_unprotect(__func__);
13232
13233 return ret;
13234}
Jeff Johnson295189b2012-06-20 16:38:30 -070013235
13236/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013237 * FUNCTION: wlan_hdd_disconnect
13238 * This function is used to issue a disconnect request to SME
13239 */
13240int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13241{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013242 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013243 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013244 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013245 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013247 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013248
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013249 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013250 if (0 != status)
13251 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013252 return status;
13253 }
13254
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013255 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13256 {
13257 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13258 pAdapter->sessionId);
13259 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013260 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013261
Agarwal Ashish47d18112014-08-04 19:55:07 +053013262 /* Need to apply spin lock before decreasing active sessions
13263 * as there can be chance for double decrement if context switch
13264 * Calls hdd_DisConnectHandler.
13265 */
13266
13267 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013268 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13269 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013270 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13271 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013272 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13273 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013274
Abhishek Singhf4669da2014-05-26 15:07:49 +053013275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013276 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13277
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013278 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013279
Mihir Shete182a0b22014-08-18 16:08:48 +053013280 /*
13281 * stop tx queues before deleting STA/BSS context from the firmware.
13282 * tx has to be disabled because the firmware can get busy dropping
13283 * the tx frames after BSS/STA has been deleted and will not send
13284 * back a response resulting in WDI timeout
13285 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013286 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013287 netif_tx_disable(pAdapter->dev);
13288 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013289
Mihir Shete182a0b22014-08-18 16:08:48 +053013290 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013291 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13292 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013293 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13294 {
13295 hddLog(VOS_TRACE_LEVEL_INFO,
13296 FL("status = %d, already disconnected"),
13297 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013298
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013299 }
13300 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013301 {
13302 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013303 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013304 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013305 result = -EINVAL;
13306 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013307 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013308 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013309 &pAdapter->disconnect_comp_var,
13310 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013311 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013312 {
13313 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013314 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013315 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013316 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013317 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013318 {
13319 hddLog(VOS_TRACE_LEVEL_ERROR,
13320 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013321 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013322 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013323disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13325 FL("Set HDD connState to eConnectionState_NotConnected"));
13326 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13327
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013328 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013329 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013330}
13331
13332
13333/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013334 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013335 * This function is used to issue a disconnect request to SME
13336 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013337static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013338 struct net_device *dev,
13339 u16 reason
13340 )
13341{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013342 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013343 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013344 tCsrRoamProfile *pRoamProfile;
13345 hdd_station_ctx_t *pHddStaCtx;
13346 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013347#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013348 tANI_U8 staIdx;
13349#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013350
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013352
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013353 if (!pAdapter) {
13354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13355 return -EINVAL;
13356 }
13357
13358 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13359 if (!pHddStaCtx) {
13360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13361 return -EINVAL;
13362 }
13363
13364 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13365 status = wlan_hdd_validate_context(pHddCtx);
13366 if (0 != status)
13367 {
13368 return status;
13369 }
13370
13371 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13372
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013373 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13374 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13375 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013376 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13377 __func__, hdd_device_modetoString(pAdapter->device_mode),
13378 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013379
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013380 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13381 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013382
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 if (NULL != pRoamProfile)
13384 {
13385 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013386 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13387 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013388 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013389 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013391 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 switch(reason)
13393 {
13394 case WLAN_REASON_MIC_FAILURE:
13395 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13396 break;
13397
13398 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13399 case WLAN_REASON_DISASSOC_AP_BUSY:
13400 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13401 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13402 break;
13403
13404 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13405 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013406 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013407 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13408 break;
13409
Jeff Johnson295189b2012-06-20 16:38:30 -070013410 default:
13411 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13412 break;
13413 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013414 pScanInfo = &pHddCtx->scan_info;
13415 if (pScanInfo->mScanPending)
13416 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013417 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013418 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013419 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013420 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013421 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013422 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013423#ifdef FEATURE_WLAN_TDLS
13424 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013425 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013426 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013427 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13428 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013429 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013430 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013431 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013433 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013434 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013435 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013436 status = sme_DeleteTdlsPeerSta(
13437 WLAN_HDD_GET_HAL_CTX(pAdapter),
13438 pAdapter->sessionId,
13439 mac);
13440 if (status != eHAL_STATUS_SUCCESS) {
13441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13442 return -EPERM;
13443 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013444 }
13445 }
13446#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013447 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013448 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13449 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013450 {
13451 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013452 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 __func__, (int)status );
13454 return -EINVAL;
13455 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013457 else
13458 {
13459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13460 "called while in %d state", __func__,
13461 pHddStaCtx->conn_info.connState);
13462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013463 }
13464 else
13465 {
13466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13467 }
13468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013469 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013470 return status;
13471}
13472
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013473static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13474 struct net_device *dev,
13475 u16 reason
13476 )
13477{
13478 int ret;
13479 vos_ssr_protect(__func__);
13480 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13481 vos_ssr_unprotect(__func__);
13482
13483 return ret;
13484}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013485
Jeff Johnson295189b2012-06-20 16:38:30 -070013486/*
13487 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013488 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013489 * settings in IBSS mode.
13490 */
13491static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013492 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 struct cfg80211_ibss_params *params
13494 )
13495{
13496 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013497 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13499 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013500
Jeff Johnson295189b2012-06-20 16:38:30 -070013501 ENTER();
13502
13503 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013504 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013505
13506 if (params->ie_len && ( NULL != params->ie) )
13507 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013508 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13509 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 {
13511 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13512 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13513 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013514 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013516 tDot11fIEWPA dot11WPAIE;
13517 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013518 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013519
Wilson Yang00256342013-10-10 23:13:38 -070013520 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013521 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13522 params->ie_len, DOT11F_EID_WPA);
13523 if ( NULL != ie )
13524 {
13525 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13526 // Unpack the WPA IE
13527 //Skip past the EID byte and length byte - and four byte WiFi OUI
13528 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13529 &ie[2+4],
13530 ie[1] - 4,
13531 &dot11WPAIE);
13532 /*Extract the multicast cipher, the encType for unicast
13533 cipher for wpa-none is none*/
13534 encryptionType =
13535 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13536 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013538
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13540
13541 if (0 > status)
13542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 __func__);
13545 return status;
13546 }
13547 }
13548
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013549 pWextState->roamProfile.AuthType.authType[0] =
13550 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13552
13553 if (params->privacy)
13554 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013555 /* Security enabled IBSS, At this time there is no information available
13556 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013558 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013560 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 *enable privacy bit in beacons */
13562
13563 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13564 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013565 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13566 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13568 pWextState->roamProfile.EncryptionType.numEntries = 1;
13569 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 return status;
13571}
13572
13573/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013574 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013575 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013577static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 struct net_device *dev,
13579 struct cfg80211_ibss_params *params
13580 )
13581{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13584 tCsrRoamProfile *pRoamProfile;
13585 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013586 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13587 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013588 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013589
13590 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013591
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013592 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13593 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13594 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013595 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013596 "%s: device_mode = %s (%d)", __func__,
13597 hdd_device_modetoString(pAdapter->device_mode),
13598 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013599
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013600 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013601 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013603 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 }
13605
13606 if (NULL == pWextState)
13607 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013608 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 __func__);
13610 return -EIO;
13611 }
13612
Agarwal Ashish51325b52014-06-16 16:50:49 +053013613 if (vos_max_concurrent_connections_reached()) {
13614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13615 return -ECONNREFUSED;
13616 }
13617
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013618 /*Try disconnecting if already in connected state*/
13619 status = wlan_hdd_try_disconnect(pAdapter);
13620 if ( 0 > status)
13621 {
13622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13623 " IBSS connection"));
13624 return -EALREADY;
13625 }
13626
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 pRoamProfile = &pWextState->roamProfile;
13628
13629 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013631 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013632 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 return -EINVAL;
13634 }
13635
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013636 /* BSSID is provided by upper layers hence no need to AUTO generate */
13637 if (NULL != params->bssid) {
13638 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13639 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13640 hddLog (VOS_TRACE_LEVEL_ERROR,
13641 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13642 return -EIO;
13643 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013644 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013645 }
krunal sonie9002db2013-11-25 14:24:17 -080013646 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13647 {
13648 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13649 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13650 {
13651 hddLog (VOS_TRACE_LEVEL_ERROR,
13652 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13653 return -EIO;
13654 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013655
13656 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013657 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013658 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013659 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013660
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013662 if (NULL !=
13663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13664 params->chandef.chan)
13665#else
13666 params->channel)
13667#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 {
13669 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013670 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13671 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13672 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13673 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013674
13675 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013676 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013677 ieee80211_frequency_to_channel(
13678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13679 params->chandef.chan->center_freq);
13680#else
13681 params->channel->center_freq);
13682#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013683
13684 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13685 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13688 __func__);
13689 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013691
13692 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013694 if (channelNum == validChan[indx])
13695 {
13696 break;
13697 }
13698 }
13699 if (indx >= numChans)
13700 {
13701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013702 __func__, channelNum);
13703 return -EINVAL;
13704 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013705 /* Set the Operational Channel */
13706 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13707 channelNum);
13708 pRoamProfile->ChannelInfo.numOfChannels = 1;
13709 pHddStaCtx->conn_info.operationChannel = channelNum;
13710 pRoamProfile->ChannelInfo.ChannelList =
13711 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 }
13713
13714 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013715 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 if (status < 0)
13717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013719 __func__);
13720 return status;
13721 }
13722
13723 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013724 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013725 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013726 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013727
13728 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013730
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013731 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013732 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013733}
13734
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013735static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13736 struct net_device *dev,
13737 struct cfg80211_ibss_params *params
13738 )
13739{
13740 int ret = 0;
13741
13742 vos_ssr_protect(__func__);
13743 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13744 vos_ssr_unprotect(__func__);
13745
13746 return ret;
13747}
13748
Jeff Johnson295189b2012-06-20 16:38:30 -070013749/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013750 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013753static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 struct net_device *dev
13755 )
13756{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013757 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013758 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13759 tCsrRoamProfile *pRoamProfile;
13760 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013761 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013762
13763 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13766 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13767 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013769 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013772 }
13773
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13775 hdd_device_modetoString(pAdapter->device_mode),
13776 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 if (NULL == pWextState)
13778 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013779 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 __func__);
13781 return -EIO;
13782 }
13783
13784 pRoamProfile = &pWextState->roamProfile;
13785
13786 /* Issue disconnect only if interface type is set to IBSS */
13787 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013789 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 __func__);
13791 return -EINVAL;
13792 }
13793
13794 /* Issue Disconnect request */
13795 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13796 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13797 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13798
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013799 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013800 return 0;
13801}
13802
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013803static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13804 struct net_device *dev
13805 )
13806{
13807 int ret = 0;
13808
13809 vos_ssr_protect(__func__);
13810 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13811 vos_ssr_unprotect(__func__);
13812
13813 return ret;
13814}
13815
Jeff Johnson295189b2012-06-20 16:38:30 -070013816/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013817 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013818 * This function is used to set the phy parameters
13819 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13820 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013821static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 u32 changed)
13823{
13824 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13825 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013826 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013827
13828 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013829
13830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013831 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13832 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013833
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013834 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013835 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013837 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013838 }
13839
Jeff Johnson295189b2012-06-20 16:38:30 -070013840 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13841 {
13842 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13843 WNI_CFG_RTS_THRESHOLD_STAMAX :
13844 wiphy->rts_threshold;
13845
13846 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013847 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013849 hddLog(VOS_TRACE_LEVEL_ERROR,
13850 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 __func__, rts_threshold);
13852 return -EINVAL;
13853 }
13854
13855 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13856 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013857 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013859 hddLog(VOS_TRACE_LEVEL_ERROR,
13860 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 __func__, rts_threshold);
13862 return -EIO;
13863 }
13864
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013865 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013866 rts_threshold);
13867 }
13868
13869 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13870 {
13871 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13872 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13873 wiphy->frag_threshold;
13874
13875 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013876 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878 hddLog(VOS_TRACE_LEVEL_ERROR,
13879 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 frag_threshold);
13881 return -EINVAL;
13882 }
13883
13884 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13885 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013886 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013888 hddLog(VOS_TRACE_LEVEL_ERROR,
13889 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 __func__, frag_threshold);
13891 return -EIO;
13892 }
13893
13894 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13895 frag_threshold);
13896 }
13897
13898 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13899 || (changed & WIPHY_PARAM_RETRY_LONG))
13900 {
13901 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13902 wiphy->retry_short :
13903 wiphy->retry_long;
13904
13905 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13906 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13907 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 __func__, retry_value);
13910 return -EINVAL;
13911 }
13912
13913 if (changed & WIPHY_PARAM_RETRY_SHORT)
13914 {
13915 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13916 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013917 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013919 hddLog(VOS_TRACE_LEVEL_ERROR,
13920 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 __func__, retry_value);
13922 return -EIO;
13923 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013924 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 __func__, retry_value);
13926 }
13927 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13928 {
13929 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13930 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013933 hddLog(VOS_TRACE_LEVEL_ERROR,
13934 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 __func__, retry_value);
13936 return -EIO;
13937 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013938 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013939 __func__, retry_value);
13940 }
13941 }
13942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013943 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 return 0;
13945}
13946
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013947static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13948 u32 changed)
13949{
13950 int ret;
13951
13952 vos_ssr_protect(__func__);
13953 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13954 vos_ssr_unprotect(__func__);
13955
13956 return ret;
13957}
13958
Jeff Johnson295189b2012-06-20 16:38:30 -070013959/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013960 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013961 * This function is used to set the txpower
13962 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013963static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013964#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13965 struct wireless_dev *wdev,
13966#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013967#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013969#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013970 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013971#endif
13972 int dbm)
13973{
13974 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013975 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13977 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013978 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013979
13980 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013981
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013982 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13983 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13984 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013985 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013986 if (0 != status)
13987 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013988 return status;
13989 }
13990
13991 hHal = pHddCtx->hHal;
13992
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013993 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13994 dbm, ccmCfgSetCallback,
13995 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013997 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13999 return -EIO;
14000 }
14001
14002 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
14003 dbm);
14004
14005 switch(type)
14006 {
14007 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
14008 /* Fall through */
14009 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
14010 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
14011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
14013 __func__);
14014 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 }
14016 break;
14017 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 __func__);
14020 return -EOPNOTSUPP;
14021 break;
14022 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
14024 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070014025 return -EIO;
14026 }
14027
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014028 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 return 0;
14030}
14031
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014032static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
14033#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14034 struct wireless_dev *wdev,
14035#endif
14036#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
14037 enum tx_power_setting type,
14038#else
14039 enum nl80211_tx_power_setting type,
14040#endif
14041 int dbm)
14042{
14043 int ret;
14044 vos_ssr_protect(__func__);
14045 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
14046#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14047 wdev,
14048#endif
14049#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
14050 type,
14051#else
14052 type,
14053#endif
14054 dbm);
14055 vos_ssr_unprotect(__func__);
14056
14057 return ret;
14058}
14059
Jeff Johnson295189b2012-06-20 16:38:30 -070014060/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014061 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070014062 * This function is used to read the txpower
14063 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014064static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070014065#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14066 struct wireless_dev *wdev,
14067#endif
14068 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070014069{
14070
14071 hdd_adapter_t *pAdapter;
14072 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014073 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014074
Jeff Johnsone7245742012-09-05 17:12:55 -070014075 ENTER();
14076
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014077 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014078 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014079 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014080 *dbm = 0;
14081 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014082 }
14083
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
14085 if (NULL == pAdapter)
14086 {
14087 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
14088 return -ENOENT;
14089 }
14090
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014091 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14092 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
14093 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 wlan_hdd_get_classAstats(pAdapter);
14095 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
14096
Jeff Johnsone7245742012-09-05 17:12:55 -070014097 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 return 0;
14099}
14100
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014101static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
14102#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14103 struct wireless_dev *wdev,
14104#endif
14105 int *dbm)
14106{
14107 int ret;
14108
14109 vos_ssr_protect(__func__);
14110 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
14111#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14112 wdev,
14113#endif
14114 dbm);
14115 vos_ssr_unprotect(__func__);
14116
14117 return ret;
14118}
14119
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014120static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14122 const u8* mac,
14123#else
14124 u8* mac,
14125#endif
14126 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070014127{
14128 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14129 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14130 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053014131 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014132
14133 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
14134 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070014135
14136 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
14137 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
14138 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
14139 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
14140 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
14141 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
14142 tANI_U16 maxRate = 0;
14143 tANI_U16 myRate;
14144 tANI_U16 currentRate = 0;
14145 tANI_U8 maxSpeedMCS = 0;
14146 tANI_U8 maxMCSIdx = 0;
14147 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053014148 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014149 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014150 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014151
Leo Chang6f8870f2013-03-26 18:11:36 -070014152#ifdef WLAN_FEATURE_11AC
14153 tANI_U32 vht_mcs_map;
14154 eDataRate11ACMaxMcs vhtMaxMcs;
14155#endif /* WLAN_FEATURE_11AC */
14156
Jeff Johnsone7245742012-09-05 17:12:55 -070014157 ENTER();
14158
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14160 (0 == ssidlen))
14161 {
14162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
14163 " Invalid ssidlen, %d", __func__, ssidlen);
14164 /*To keep GUI happy*/
14165 return 0;
14166 }
14167
Mukul Sharma811205f2014-07-09 21:07:30 +053014168 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
14169 {
14170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14171 "%s: Roaming in progress, so unable to proceed this request", __func__);
14172 return 0;
14173 }
14174
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014175 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014176 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014177 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014178 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014179 }
14180
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053014181 wlan_hdd_get_station_stats(pAdapter);
14182 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014183
Kiet Lam3b17fc82013-09-27 05:24:08 +053014184 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
14185 sinfo->filled |= STATION_INFO_SIGNAL;
14186
c_hpothu09f19542014-05-30 21:53:31 +053014187 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053014188 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
14189 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053014190 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053014191 {
14192 rate_flags = pAdapter->maxRateFlags;
14193 }
c_hpothu44ff4e02014-05-08 00:13:57 +053014194
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 //convert to the UI units of 100kbps
14196 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
14197
14198#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070014199 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 -070014200 sinfo->signal,
14201 pCfg->reportMaxLinkSpeed,
14202 myRate,
14203 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014204 (int) pCfg->linkSpeedRssiMid,
14205 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070014206 (int) rate_flags,
14207 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070014208#endif //LINKSPEED_DEBUG_ENABLED
14209
14210 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
14211 {
14212 // we do not want to necessarily report the current speed
14213 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
14214 {
14215 // report the max possible speed
14216 rssidx = 0;
14217 }
14218 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
14219 {
14220 // report the max possible speed with RSSI scaling
14221 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
14222 {
14223 // report the max possible speed
14224 rssidx = 0;
14225 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014226 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070014227 {
14228 // report middle speed
14229 rssidx = 1;
14230 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014231 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
14232 {
14233 // report middle speed
14234 rssidx = 2;
14235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014236 else
14237 {
14238 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014239 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070014240 }
14241 }
14242 else
14243 {
14244 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14245 hddLog(VOS_TRACE_LEVEL_ERROR,
14246 "%s: Invalid value for reportMaxLinkSpeed: %u",
14247 __func__, pCfg->reportMaxLinkSpeed);
14248 rssidx = 0;
14249 }
14250
14251 maxRate = 0;
14252
14253 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014254 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14255 OperationalRates, &ORLeng))
14256 {
14257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14258 /*To keep GUI happy*/
14259 return 0;
14260 }
14261
Jeff Johnson295189b2012-06-20 16:38:30 -070014262 for (i = 0; i < ORLeng; i++)
14263 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014264 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 {
14266 /* Validate Rate Set */
14267 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14268 {
14269 currentRate = supported_data_rate[j].supported_rate[rssidx];
14270 break;
14271 }
14272 }
14273 /* Update MAX rate */
14274 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14275 }
14276
14277 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014278 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14279 ExtendedRates, &ERLeng))
14280 {
14281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14282 /*To keep GUI happy*/
14283 return 0;
14284 }
14285
Jeff Johnson295189b2012-06-20 16:38:30 -070014286 for (i = 0; i < ERLeng; i++)
14287 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014288 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 {
14290 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14291 {
14292 currentRate = supported_data_rate[j].supported_rate[rssidx];
14293 break;
14294 }
14295 }
14296 /* Update MAX rate */
14297 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14298 }
c_hpothu79aab322014-07-14 21:11:01 +053014299
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014300 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014301 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014302 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014303 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014304 {
c_hpothu79aab322014-07-14 21:11:01 +053014305 if (rate_flags & eHAL_TX_RATE_VHT80)
14306 mode = 2;
14307 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14308 mode = 1;
14309 else
14310 mode = 0;
14311
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014312 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14313 MCSRates, &MCSLeng))
14314 {
14315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14316 /*To keep GUI happy*/
14317 return 0;
14318 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014320#ifdef WLAN_FEATURE_11AC
14321 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014322 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014324 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014325 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014326 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014327 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014328 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014329 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014330 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014331 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014332 maxMCSIdx = 7;
14333 }
14334 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14335 {
14336 maxMCSIdx = 8;
14337 }
14338 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14339 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014340 //VHT20 is supporting 0~8
14341 if (rate_flags & eHAL_TX_RATE_VHT20)
14342 maxMCSIdx = 8;
14343 else
14344 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014345 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014346
c_hpothu79aab322014-07-14 21:11:01 +053014347 if (0 != rssidx)/*check for scaled */
14348 {
14349 //get middle rate MCS index if rssi=1/2
14350 for (i=0; i <= maxMCSIdx; i++)
14351 {
14352 if (sinfo->signal <= rssiMcsTbl[mode][i])
14353 {
14354 maxMCSIdx = i;
14355 break;
14356 }
14357 }
14358 }
14359
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014360 if (rate_flags & eHAL_TX_RATE_VHT80)
14361 {
14362 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14363 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14364 }
14365 else if (rate_flags & eHAL_TX_RATE_VHT40)
14366 {
14367 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14368 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14369 }
14370 else if (rate_flags & eHAL_TX_RATE_VHT20)
14371 {
14372 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14373 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14374 }
14375
Leo Chang6f8870f2013-03-26 18:11:36 -070014376 maxSpeedMCS = 1;
14377 if (currentRate > maxRate)
14378 {
14379 maxRate = currentRate;
14380 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014381
Leo Chang6f8870f2013-03-26 18:11:36 -070014382 }
14383 else
14384#endif /* WLAN_FEATURE_11AC */
14385 {
14386 if (rate_flags & eHAL_TX_RATE_HT40)
14387 {
14388 rateFlag |= 1;
14389 }
14390 if (rate_flags & eHAL_TX_RATE_SGI)
14391 {
14392 rateFlag |= 2;
14393 }
14394
Girish Gowli01abcee2014-07-31 20:18:55 +053014395 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014396 if (rssidx == 1 || rssidx == 2)
14397 {
14398 //get middle rate MCS index if rssi=1/2
14399 for (i=0; i <= 7; i++)
14400 {
14401 if (sinfo->signal <= rssiMcsTbl[mode][i])
14402 {
14403 temp = i+1;
14404 break;
14405 }
14406 }
14407 }
c_hpothu79aab322014-07-14 21:11:01 +053014408
14409 for (i = 0; i < MCSLeng; i++)
14410 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014411 for (j = 0; j < temp; j++)
14412 {
14413 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14414 {
14415 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014416 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014417 break;
14418 }
14419 }
14420 if ((j < temp) && (currentRate > maxRate))
14421 {
14422 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014424 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014425 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 }
14427 }
14428
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014429 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14430 {
14431 maxRate = myRate;
14432 maxSpeedMCS = 1;
14433 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14434 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014435 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014436 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014437 {
14438 maxRate = myRate;
14439 if (rate_flags & eHAL_TX_RATE_LEGACY)
14440 {
14441 maxSpeedMCS = 0;
14442 }
14443 else
14444 {
14445 maxSpeedMCS = 1;
14446 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14447 }
14448 }
14449
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014450 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014451 {
14452 sinfo->txrate.legacy = maxRate;
14453#ifdef LINKSPEED_DEBUG_ENABLED
14454 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14455#endif //LINKSPEED_DEBUG_ENABLED
14456 }
14457 else
14458 {
14459 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014460#ifdef WLAN_FEATURE_11AC
14461 sinfo->txrate.nss = 1;
14462 if (rate_flags & eHAL_TX_RATE_VHT80)
14463 {
14464 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014465 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014466 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014467 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014468 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014469 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14470 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14471 }
14472 else if (rate_flags & eHAL_TX_RATE_VHT20)
14473 {
14474 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14475 }
14476#endif /* WLAN_FEATURE_11AC */
14477 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14478 {
14479 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14480 if (rate_flags & eHAL_TX_RATE_HT40)
14481 {
14482 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14483 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014485 if (rate_flags & eHAL_TX_RATE_SGI)
14486 {
14487 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14488 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014489
Jeff Johnson295189b2012-06-20 16:38:30 -070014490#ifdef LINKSPEED_DEBUG_ENABLED
14491 pr_info("Reporting MCS rate %d flags %x\n",
14492 sinfo->txrate.mcs,
14493 sinfo->txrate.flags );
14494#endif //LINKSPEED_DEBUG_ENABLED
14495 }
14496 }
14497 else
14498 {
14499 // report current rate instead of max rate
14500
14501 if (rate_flags & eHAL_TX_RATE_LEGACY)
14502 {
14503 //provide to the UI in units of 100kbps
14504 sinfo->txrate.legacy = myRate;
14505#ifdef LINKSPEED_DEBUG_ENABLED
14506 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14507#endif //LINKSPEED_DEBUG_ENABLED
14508 }
14509 else
14510 {
14511 //must be MCS
14512 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014513#ifdef WLAN_FEATURE_11AC
14514 sinfo->txrate.nss = 1;
14515 if (rate_flags & eHAL_TX_RATE_VHT80)
14516 {
14517 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14518 }
14519 else
14520#endif /* WLAN_FEATURE_11AC */
14521 {
14522 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14523 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 if (rate_flags & eHAL_TX_RATE_SGI)
14525 {
14526 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14527 }
14528 if (rate_flags & eHAL_TX_RATE_HT40)
14529 {
14530 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14531 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014532#ifdef WLAN_FEATURE_11AC
14533 else if (rate_flags & eHAL_TX_RATE_VHT80)
14534 {
14535 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14536 }
14537#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014538#ifdef LINKSPEED_DEBUG_ENABLED
14539 pr_info("Reporting actual MCS rate %d flags %x\n",
14540 sinfo->txrate.mcs,
14541 sinfo->txrate.flags );
14542#endif //LINKSPEED_DEBUG_ENABLED
14543 }
14544 }
14545 sinfo->filled |= STATION_INFO_TX_BITRATE;
14546
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014547 sinfo->tx_packets =
14548 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14549 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14550 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14551 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14552
14553 sinfo->tx_retries =
14554 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14555 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14556 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14557 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14558
14559 sinfo->tx_failed =
14560 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14561 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14562 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14563 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14564
14565 sinfo->filled |=
14566 STATION_INFO_TX_PACKETS |
14567 STATION_INFO_TX_RETRIES |
14568 STATION_INFO_TX_FAILED;
14569
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014570 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14571 TRACE_CODE_HDD_CFG80211_GET_STA,
14572 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014573 EXIT();
14574 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014575}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014576#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14577static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14578 const u8* mac, struct station_info *sinfo)
14579#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014580static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14581 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014582#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014583{
14584 int ret;
14585
14586 vos_ssr_protect(__func__);
14587 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14588 vos_ssr_unprotect(__func__);
14589
14590 return ret;
14591}
14592
14593static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014594 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014595{
14596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014597 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014598 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014599 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014600
Jeff Johnsone7245742012-09-05 17:12:55 -070014601 ENTER();
14602
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 if (NULL == pAdapter)
14604 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014606 return -ENODEV;
14607 }
14608
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14610 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14611 pAdapter->sessionId, timeout));
14612
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014613 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014614 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014615 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014616 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014617 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014618 }
14619
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014620 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14621 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14622 (pHddCtx->cfg_ini->fhostArpOffload) &&
14623 (eConnectionState_Associated ==
14624 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14625 {
Amar Singhald53568e2013-09-26 11:03:45 -070014626
14627 hddLog(VOS_TRACE_LEVEL_INFO,
14628 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014629 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014630 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14631 {
14632 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014633 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014634 __func__, vos_status);
14635 }
14636 }
14637
Jeff Johnson295189b2012-06-20 16:38:30 -070014638 /**The get power cmd from the supplicant gets updated by the nl only
14639 *on successful execution of the function call
14640 *we are oppositely mapped w.r.t mode in the driver
14641 **/
14642 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14643
14644 if (VOS_STATUS_E_FAILURE == vos_status)
14645 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14647 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014648 return -EINVAL;
14649 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014650 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 return 0;
14652}
14653
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014654static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14655 struct net_device *dev, bool mode, int timeout)
14656{
14657 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014658
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014659 vos_ssr_protect(__func__);
14660 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14661 vos_ssr_unprotect(__func__);
14662
14663 return ret;
14664}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014665
Jeff Johnson295189b2012-06-20 16:38:30 -070014666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014667static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14668 struct net_device *netdev,
14669 u8 key_index)
14670{
14671 ENTER();
14672 return 0;
14673}
14674
Jeff Johnson295189b2012-06-20 16:38:30 -070014675static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014676 struct net_device *netdev,
14677 u8 key_index)
14678{
14679 int ret;
14680 vos_ssr_protect(__func__);
14681 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14682 vos_ssr_unprotect(__func__);
14683 return ret;
14684}
14685#endif //LINUX_VERSION_CODE
14686
14687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14688static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14689 struct net_device *dev,
14690 struct ieee80211_txq_params *params)
14691{
14692 ENTER();
14693 return 0;
14694}
14695#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14696static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14697 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014698{
Jeff Johnsone7245742012-09-05 17:12:55 -070014699 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 return 0;
14701}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014702#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014703
14704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14705static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014706 struct net_device *dev,
14707 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014708{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014709 int ret;
14710
14711 vos_ssr_protect(__func__);
14712 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14713 vos_ssr_unprotect(__func__);
14714 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014715}
14716#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14717static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14718 struct ieee80211_txq_params *params)
14719{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014720 int ret;
14721
14722 vos_ssr_protect(__func__);
14723 ret = __wlan_hdd_set_txq_params(wiphy, params);
14724 vos_ssr_unprotect(__func__);
14725 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014726}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014727#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014728
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014729static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014730 struct net_device *dev,
14731 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014732{
14733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014734 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014735 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014736 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014737 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014738 v_CONTEXT_t pVosContext = NULL;
14739 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014740
Jeff Johnsone7245742012-09-05 17:12:55 -070014741 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014742
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014743 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014746 return -EINVAL;
14747 }
14748
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014749 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14750 TRACE_CODE_HDD_CFG80211_DEL_STA,
14751 pAdapter->sessionId, pAdapter->device_mode));
14752
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014753 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14754 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014755 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014756 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014757 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014758 }
14759
Jeff Johnson295189b2012-06-20 16:38:30 -070014760 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014762 )
14763 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014764 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14765 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14766 if(pSapCtx == NULL){
14767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14768 FL("psapCtx is NULL"));
14769 return -ENOENT;
14770 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014771 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014772 {
14773 v_U16_t i;
14774 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14775 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014776 if ((pSapCtx->aStaInfo[i].isUsed) &&
14777 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014779 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014780 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014781 ETHER_ADDR_LEN);
14782
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014784 "%s: Delete STA with MAC::"
14785 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014786 __func__,
14787 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14788 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014789 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014790 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014791 }
14792 }
14793 }
14794 else
14795 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014796
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014797 vos_status = hdd_softap_GetStaId(pAdapter,
14798 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014799 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14800 {
14801 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014802 "%s: Skip this DEL STA as this is not used::"
14803 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014804 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014805 return -ENOENT;
14806 }
14807
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014808 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014809 {
14810 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014811 "%s: Skip this DEL STA as deauth is in progress::"
14812 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014813 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014814 return -ENOENT;
14815 }
14816
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014817 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014818
Jeff Johnson295189b2012-06-20 16:38:30 -070014819 hddLog(VOS_TRACE_LEVEL_INFO,
14820 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014821 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014822 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014823 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014824
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014825 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014826 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14827 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014828 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014829 hddLog(VOS_TRACE_LEVEL_INFO,
14830 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014831 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014832 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014833 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014834 return -ENOENT;
14835 }
14836
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 }
14838 }
14839
14840 EXIT();
14841
14842 return 0;
14843}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014844
14845#ifdef CFG80211_DEL_STA_V2
14846static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14847 struct net_device *dev,
14848 struct station_del_parameters *param)
14849#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14851static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14852 struct net_device *dev, const u8 *mac)
14853#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014854static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14855 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014856#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014857#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014858{
14859 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014860 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014861
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014862 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014863
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014864#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014865 if (NULL == param) {
14866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014867 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014868 return -EINVAL;
14869 }
14870
14871 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14872 param->subtype, &delStaParams);
14873
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014874#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014875 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014876 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014877#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014878 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14879
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014880 vos_ssr_unprotect(__func__);
14881
14882 return ret;
14883}
14884
14885static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014886 struct net_device *dev,
14887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14888 const u8 *mac,
14889#else
14890 u8 *mac,
14891#endif
14892 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014893{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014894 hdd_adapter_t *pAdapter;
14895 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014896 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014897#ifdef FEATURE_WLAN_TDLS
14898 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014899
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014900 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014901
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014902 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14903 if (NULL == pAdapter)
14904 {
14905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14906 "%s: Adapter is NULL",__func__);
14907 return -EINVAL;
14908 }
14909 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14910 status = wlan_hdd_validate_context(pHddCtx);
14911 if (0 != status)
14912 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014913 return status;
14914 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014915
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014916 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14917 TRACE_CODE_HDD_CFG80211_ADD_STA,
14918 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014919 mask = params->sta_flags_mask;
14920
14921 set = params->sta_flags_set;
14922
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014924 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14925 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014926
14927 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14928 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014929 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014930 }
14931 }
14932#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014933 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014934 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014935}
14936
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14938static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14939 struct net_device *dev, const u8 *mac,
14940 struct station_parameters *params)
14941#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014942static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14943 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014944#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014945{
14946 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014947
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014948 vos_ssr_protect(__func__);
14949 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14950 vos_ssr_unprotect(__func__);
14951
14952 return ret;
14953}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014954#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014955
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014956static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014957 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014958{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14960 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014961 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014962 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014963 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014964 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014965
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014966 ENTER();
14967
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014968 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014969 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014970 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014972 return -EINVAL;
14973 }
14974
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014975 if (!pmksa) {
14976 hddLog(LOGE, FL("pmksa is NULL"));
14977 return -EINVAL;
14978 }
14979
14980 if (!pmksa->bssid || !pmksa->pmkid) {
14981 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14982 pmksa->bssid, pmksa->pmkid);
14983 return -EINVAL;
14984 }
14985
14986 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14987 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14988
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014989 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14990 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014991 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014992 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014993 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014994 }
14995
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014996 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014997 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14998
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014999 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
15000 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015001
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015002 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015003 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015004 &pmk_id, 1, FALSE);
15005
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015006 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15007 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
15008 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015009
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015010 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015011 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015012}
15013
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015014static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
15015 struct cfg80211_pmksa *pmksa)
15016{
15017 int ret;
15018
15019 vos_ssr_protect(__func__);
15020 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
15021 vos_ssr_unprotect(__func__);
15022
15023 return ret;
15024}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015025
Wilson Yang6507c4e2013-10-01 20:11:19 -070015026
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015027static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070015028 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015029{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15031 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015032 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015033 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015035 ENTER();
15036
Wilson Yang6507c4e2013-10-01 20:11:19 -070015037 /* Validate pAdapter */
15038 if (NULL == pAdapter)
15039 {
15040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
15041 return -EINVAL;
15042 }
15043
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015044 if (!pmksa) {
15045 hddLog(LOGE, FL("pmksa is NULL"));
15046 return -EINVAL;
15047 }
15048
15049 if (!pmksa->bssid) {
15050 hddLog(LOGE, FL("pmksa->bssid is NULL"));
15051 return -EINVAL;
15052 }
15053
Kiet Lam98c46a12014-10-31 15:34:57 -070015054 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
15055 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15056
Wilson Yang6507c4e2013-10-01 20:11:19 -070015057 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15058 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015059 if (0 != status)
15060 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015061 return status;
15062 }
15063
15064 /*Retrieve halHandle*/
15065 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15066
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15068 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
15069 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015070 /* Delete the PMKID CSR cache */
15071 if (eHAL_STATUS_SUCCESS !=
15072 sme_RoamDelPMKIDfromCache(halHandle,
15073 pAdapter->sessionId, pmksa->bssid, FALSE)) {
15074 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
15075 MAC_ADDR_ARRAY(pmksa->bssid));
15076 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015077 }
15078
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015079 EXIT();
15080 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015081}
15082
Wilson Yang6507c4e2013-10-01 20:11:19 -070015083
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015084static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
15085 struct cfg80211_pmksa *pmksa)
15086{
15087 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015088
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015089 vos_ssr_protect(__func__);
15090 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
15091 vos_ssr_unprotect(__func__);
15092
15093 return ret;
15094
15095}
15096
15097static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015098{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15100 tHalHandle halHandle;
15101 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015102 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015103
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015104 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070015105
15106 /* Validate pAdapter */
15107 if (NULL == pAdapter)
15108 {
15109 hddLog(VOS_TRACE_LEVEL_ERROR,
15110 "%s: Invalid Adapter" ,__func__);
15111 return -EINVAL;
15112 }
15113
15114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15115 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015116 if (0 != status)
15117 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015118 return status;
15119 }
15120
15121 /*Retrieve halHandle*/
15122 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15123
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015124 /* Flush the PMKID cache in CSR */
15125 if (eHAL_STATUS_SUCCESS !=
15126 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
15127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
15128 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015129 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015130 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080015131 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015132}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015133
15134static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
15135{
15136 int ret;
15137
15138 vos_ssr_protect(__func__);
15139 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
15140 vos_ssr_unprotect(__func__);
15141
15142 return ret;
15143}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015144#endif
15145
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015146#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015147static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15148 struct net_device *dev,
15149 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015150{
15151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15152 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015153 hdd_context_t *pHddCtx;
15154 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015155
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015156 ENTER();
15157
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015158 if (NULL == pAdapter)
15159 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015160 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015161 return -ENODEV;
15162 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015163 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15164 ret = wlan_hdd_validate_context(pHddCtx);
15165 if (0 != ret)
15166 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015167 return ret;
15168 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015169 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015170 if (NULL == pHddStaCtx)
15171 {
15172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15173 return -EINVAL;
15174 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015175
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015176 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15177 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15178 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015179 // Added for debug on reception of Re-assoc Req.
15180 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15181 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015182 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015183 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015184 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015185 }
15186
15187#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015188 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015189 ftie->ie_len);
15190#endif
15191
15192 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015193 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15194 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015195 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015196
15197 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015198 return 0;
15199}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015200
15201static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15202 struct net_device *dev,
15203 struct cfg80211_update_ft_ies_params *ftie)
15204{
15205 int ret;
15206
15207 vos_ssr_protect(__func__);
15208 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15209 vos_ssr_unprotect(__func__);
15210
15211 return ret;
15212}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015213#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015214
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015215#ifdef FEATURE_WLAN_SCAN_PNO
15216
15217void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15218 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15219{
15220 int ret;
15221 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15222 hdd_context_t *pHddCtx;
15223
Nirav Shah80830bf2013-12-31 16:35:12 +053015224 ENTER();
15225
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015226 if (NULL == pAdapter)
15227 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015229 "%s: HDD adapter is Null", __func__);
15230 return ;
15231 }
15232
15233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15234 if (NULL == pHddCtx)
15235 {
15236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15237 "%s: HDD context is Null!!!", __func__);
15238 return ;
15239 }
15240
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015241 spin_lock(&pHddCtx->schedScan_lock);
15242 if (TRUE == pHddCtx->isWiphySuspended)
15243 {
15244 pHddCtx->isSchedScanUpdatePending = TRUE;
15245 spin_unlock(&pHddCtx->schedScan_lock);
15246 hddLog(VOS_TRACE_LEVEL_INFO,
15247 "%s: Update cfg80211 scan database after it resume", __func__);
15248 return ;
15249 }
15250 spin_unlock(&pHddCtx->schedScan_lock);
15251
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015252 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15253
15254 if (0 > ret)
15255 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15256
15257 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15259 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015260}
15261
15262/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015263 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015264 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015265 */
15266static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15267{
15268 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15269 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015270 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015271 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15272 int status = 0;
15273 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15274
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015275 /* The current firmware design does not allow PNO during any
15276 * active sessions. Hence, determine the active sessions
15277 * and return a failure.
15278 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015279 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15280 {
15281 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015282 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015283
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015284 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15285 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15286 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15287 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15288 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015289 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015290 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015291 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015292 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015293 }
15294 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15295 pAdapterNode = pNext;
15296 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015297 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015298}
15299
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015300void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15301{
15302 hdd_adapter_t *pAdapter = callbackContext;
15303 hdd_context_t *pHddCtx;
15304
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015305 ENTER();
15306
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015307 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15308 {
15309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15310 FL("Invalid adapter or adapter has invalid magic"));
15311 return;
15312 }
15313
15314 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15315 if (0 != wlan_hdd_validate_context(pHddCtx))
15316 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015317 return;
15318 }
15319
c_hpothub53c45d2014-08-18 16:53:14 +053015320 if (VOS_STATUS_SUCCESS != status)
15321 {
15322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015323 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015324 pHddCtx->isPnoEnable = FALSE;
15325 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015326
15327 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15328 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015329 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015330}
15331
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015332/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015333 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15334 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015335 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015336static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015337 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15338{
15339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015340 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015341 hdd_context_t *pHddCtx;
15342 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015343 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015344 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15345 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015346 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15347 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015348 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015349 hdd_config_t *pConfig = NULL;
15350 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015352 ENTER();
15353
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015354 if (NULL == pAdapter)
15355 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015357 "%s: HDD adapter is Null", __func__);
15358 return -ENODEV;
15359 }
15360
15361 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015362 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015363
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015364 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015365 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015366 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015367 }
15368
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015369 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015370 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15371 if (NULL == hHal)
15372 {
15373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15374 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015375 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015376 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015377 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15378 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15379 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015380 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015381 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015382 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015383 {
15384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15385 "%s: aborting the existing scan is unsuccessfull", __func__);
15386 return -EBUSY;
15387 }
15388
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015389 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015390 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015392 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015393 return -EBUSY;
15394 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015395
c_hpothu37f21312014-04-09 21:49:54 +053015396 if (TRUE == pHddCtx->isPnoEnable)
15397 {
15398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15399 FL("already PNO is enabled"));
15400 return -EBUSY;
15401 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015402
15403 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15404 {
15405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15406 "%s: abort ROC failed ", __func__);
15407 return -EBUSY;
15408 }
15409
c_hpothu37f21312014-04-09 21:49:54 +053015410 pHddCtx->isPnoEnable = TRUE;
15411
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015412 pnoRequest.enable = 1; /*Enable PNO */
15413 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015414
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015415 if (( !pnoRequest.ucNetworksCount ) ||
15416 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015417 {
15418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015419 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015420 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015421 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015422 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015423 goto error;
15424 }
15425
15426 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15427 {
15428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015429 "%s: Incorrect number of channels %d",
15430 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015431 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015432 goto error;
15433 }
15434
15435 /* Framework provides one set of channels(all)
15436 * common for all saved profile */
15437 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15438 channels_allowed, &num_channels_allowed))
15439 {
15440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15441 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015442 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015443 goto error;
15444 }
15445 /* Checking each channel against allowed channel list */
15446 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015447 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015448 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015449 char chList [(request->n_channels*5)+1];
15450 int len;
15451 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015452 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015453 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015454 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015455 if (request->channels[i]->hw_value == channels_allowed[indx])
15456 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015457 if ((!pConfig->enableDFSPnoChnlScan) &&
15458 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15459 {
15460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15461 "%s : Dropping DFS channel : %d",
15462 __func__,channels_allowed[indx]);
15463 num_ignore_dfs_ch++;
15464 break;
15465 }
15466
Nirav Shah80830bf2013-12-31 16:35:12 +053015467 valid_ch[num_ch++] = request->channels[i]->hw_value;
15468 len += snprintf(chList+len, 5, "%d ",
15469 request->channels[i]->hw_value);
15470 break ;
15471 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015472 }
15473 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015474 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015475
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015476 /*If all channels are DFS and dropped, then ignore the PNO request*/
15477 if (num_ignore_dfs_ch == request->n_channels)
15478 {
15479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15480 "%s : All requested channels are DFS channels", __func__);
15481 ret = -EINVAL;
15482 goto error;
15483 }
15484 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015485
15486 pnoRequest.aNetworks =
15487 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15488 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015489 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015490 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15491 FL("failed to allocate memory aNetworks %u"),
15492 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15493 goto error;
15494 }
15495 vos_mem_zero(pnoRequest.aNetworks,
15496 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15497
15498 /* Filling per profile params */
15499 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15500 {
15501 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015502 request->match_sets[i].ssid.ssid_len;
15503
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015504 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15505 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015506 {
15507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015508 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015509 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015510 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015511 goto error;
15512 }
15513
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015514 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015515 request->match_sets[i].ssid.ssid,
15516 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15518 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015519 i, pnoRequest.aNetworks[i].ssId.ssId);
15520 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15521 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15522 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015523
15524 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015525 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15526 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015527
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015528 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015529 }
15530
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015531 for (i = 0; i < request->n_ssids; i++)
15532 {
15533 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015534 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015535 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015536 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015537 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015538 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015539 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015540 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015541 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015542 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015543 break;
15544 }
15545 j++;
15546 }
15547 }
15548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15549 "Number of hidden networks being Configured = %d",
15550 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015552 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015553
15554 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15555 if (pnoRequest.p24GProbeTemplate == NULL)
15556 {
15557 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15558 FL("failed to allocate memory p24GProbeTemplate %u"),
15559 SIR_PNO_MAX_PB_REQ_SIZE);
15560 goto error;
15561 }
15562
15563 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15564 if (pnoRequest.p5GProbeTemplate == NULL)
15565 {
15566 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15567 FL("failed to allocate memory p5GProbeTemplate %u"),
15568 SIR_PNO_MAX_PB_REQ_SIZE);
15569 goto error;
15570 }
15571
15572 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15573 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15574
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015575 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15576 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015577 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015578 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15579 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15580 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015581
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015582 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15583 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15584 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015585 }
15586
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015587 /* Driver gets only one time interval which is hardcoded in
15588 * supplicant for 10000ms. Taking power consumption into account 6 timers
15589 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15590 * 80,160,320 secs. And number of scan cycle for each timer
15591 * is configurable through INI param gPNOScanTimerRepeatValue.
15592 * If it is set to 0 only one timer will be used and PNO scan cycle
15593 * will be repeated after each interval specified by supplicant
15594 * till PNO is disabled.
15595 */
15596 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015597 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015598 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015599 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015600 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15601
15602 tempInterval = (request->interval)/1000;
15603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15604 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15605 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015606 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015607 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015608 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015609 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015610 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015611 tempInterval *= 2;
15612 }
15613 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015614 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015615
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015616 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015617
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015618 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015619 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15620 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015621 pAdapter->pno_req_status = 0;
15622
Nirav Shah80830bf2013-12-31 16:35:12 +053015623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15624 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015625 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15626 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015627
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015628 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015629 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015630 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15631 if (eHAL_STATUS_SUCCESS != status)
15632 {
15633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015634 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015635 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015636 goto error;
15637 }
15638
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015639 ret = wait_for_completion_timeout(
15640 &pAdapter->pno_comp_var,
15641 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15642 if (0 >= ret)
15643 {
15644 // Did not receive the response for PNO enable in time.
15645 // Assuming the PNO enable was success.
15646 // Returning error from here, because we timeout, results
15647 // in side effect of Wifi (Wifi Setting) not to work.
15648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15649 FL("Timed out waiting for PNO to be Enabled"));
15650 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015651 }
15652
15653 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015654 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015655
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015656error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15658 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015659 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015660 if (pnoRequest.aNetworks)
15661 vos_mem_free(pnoRequest.aNetworks);
15662 if (pnoRequest.p24GProbeTemplate)
15663 vos_mem_free(pnoRequest.p24GProbeTemplate);
15664 if (pnoRequest.p5GProbeTemplate)
15665 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015666
15667 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015668 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015669}
15670
15671/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015672 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15673 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015674 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015675static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15676 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15677{
15678 int ret;
15679
15680 vos_ssr_protect(__func__);
15681 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15682 vos_ssr_unprotect(__func__);
15683
15684 return ret;
15685}
15686
15687/*
15688 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15689 * Function to disable PNO
15690 */
15691static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015692 struct net_device *dev)
15693{
15694 eHalStatus status = eHAL_STATUS_FAILURE;
15695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15696 hdd_context_t *pHddCtx;
15697 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015698 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015699 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015700
15701 ENTER();
15702
15703 if (NULL == pAdapter)
15704 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015706 "%s: HDD adapter is Null", __func__);
15707 return -ENODEV;
15708 }
15709
15710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015711
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015712 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015713 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015715 "%s: HDD context is Null", __func__);
15716 return -ENODEV;
15717 }
15718
15719 /* The return 0 is intentional when isLogpInProgress and
15720 * isLoadUnloadInProgress. We did observe a crash due to a return of
15721 * failure in sched_scan_stop , especially for a case where the unload
15722 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15723 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15724 * success. If it returns a failure , then its next invocation due to the
15725 * clean up of the second interface will have the dev pointer corresponding
15726 * to the first one leading to a crash.
15727 */
15728 if (pHddCtx->isLogpInProgress)
15729 {
15730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15731 "%s: LOGP in Progress. Ignore!!!", __func__);
15732 return ret;
15733 }
15734
Mihir Shete18156292014-03-11 15:38:30 +053015735 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015736 {
15737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15738 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15739 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015740 }
15741
15742 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15743 if (NULL == hHal)
15744 {
15745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15746 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015747 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015748 }
15749
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015750 pnoRequest.enable = 0; /* Disable PNO */
15751 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015752
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015753 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15754 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15755 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015756 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015757 pAdapter->sessionId,
15758 NULL, pAdapter);
15759 if (eHAL_STATUS_SUCCESS != status)
15760 {
15761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15762 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015763 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015764 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015765 }
c_hpothu37f21312014-04-09 21:49:54 +053015766 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015767
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015768error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015770 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015771
15772 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015773 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015774}
15775
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015776/*
15777 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15778 * NL interface to disable PNO
15779 */
15780static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15781 struct net_device *dev)
15782{
15783 int ret;
15784
15785 vos_ssr_protect(__func__);
15786 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15787 vos_ssr_unprotect(__func__);
15788
15789 return ret;
15790}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015791#endif /*FEATURE_WLAN_SCAN_PNO*/
15792
15793
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015794#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015795#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015796static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15797 struct net_device *dev,
15798 u8 *peer, u8 action_code,
15799 u8 dialog_token,
15800 u16 status_code, u32 peer_capability,
15801 const u8 *buf, size_t len)
15802#else /* TDLS_MGMT_VERSION2 */
15803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15804static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15805 struct net_device *dev,
15806 const u8 *peer, u8 action_code,
15807 u8 dialog_token, u16 status_code,
15808 u32 peer_capability, bool initiator,
15809 const u8 *buf, size_t len)
15810#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15811static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15812 struct net_device *dev,
15813 const u8 *peer, u8 action_code,
15814 u8 dialog_token, u16 status_code,
15815 u32 peer_capability, const u8 *buf,
15816 size_t len)
15817#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15818static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15819 struct net_device *dev,
15820 u8 *peer, u8 action_code,
15821 u8 dialog_token,
15822 u16 status_code, u32 peer_capability,
15823 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015824#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015825static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15826 struct net_device *dev,
15827 u8 *peer, u8 action_code,
15828 u8 dialog_token,
15829 u16 status_code, const u8 *buf,
15830 size_t len)
15831#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015832#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015833{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015834 hdd_adapter_t *pAdapter;
15835 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015836 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015837 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015838 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015839 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015840 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015841#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015842 u32 peer_capability = 0;
15843#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015844 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015845 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015846
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015847 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15848 if (NULL == pAdapter)
15849 {
15850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15851 "%s: Adapter is NULL",__func__);
15852 return -EINVAL;
15853 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015854 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15855 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15856 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015857
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015858 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015859 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015862 "Invalid arguments");
15863 return -EINVAL;
15864 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015865
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015866 if (pHddCtx->isLogpInProgress)
15867 {
15868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15869 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015870 wlan_hdd_tdls_set_link_status(pAdapter,
15871 peer,
15872 eTDLS_LINK_IDLE,
15873 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015874 return -EBUSY;
15875 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015876
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015877 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15878 {
15879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15880 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15881 return -EAGAIN;
15882 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015883
Hoonki Lee27511902013-03-14 18:19:06 -070015884 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015885 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015887 "%s: TDLS mode is disabled OR not enabled in FW."
15888 MAC_ADDRESS_STR " action %d declined.",
15889 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015890 return -ENOTSUPP;
15891 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015892
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15894
15895 if( NULL == pHddStaCtx )
15896 {
15897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15898 "%s: HDD station context NULL ",__func__);
15899 return -EINVAL;
15900 }
15901
15902 /* STA should be connected and authenticated
15903 * before sending any TDLS frames
15904 */
15905 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15906 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15907 {
15908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15909 "STA is not connected or unauthenticated. "
15910 "connState %u, uIsAuthenticated %u",
15911 pHddStaCtx->conn_info.connState,
15912 pHddStaCtx->conn_info.uIsAuthenticated);
15913 return -EAGAIN;
15914 }
15915
Hoonki Lee27511902013-03-14 18:19:06 -070015916 /* other than teardown frame, other mgmt frames are not sent if disabled */
15917 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15918 {
15919 /* if tdls_mode is disabled to respond to peer's request */
15920 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15921 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015923 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015924 " TDLS mode is disabled. action %d declined.",
15925 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015926
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015927 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015928 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015929
15930 if (vos_max_concurrent_connections_reached())
15931 {
15932 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15933 return -EINVAL;
15934 }
Hoonki Lee27511902013-03-14 18:19:06 -070015935 }
15936
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015937 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15938 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015939 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015940 {
15941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015942 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015943 " TDLS setup is ongoing. action %d declined.",
15944 __func__, MAC_ADDR_ARRAY(peer), action_code);
15945 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015946 }
15947 }
15948
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015949 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15950 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015951 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015952 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15953 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015954 {
15955 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15956 we return error code at 'add_station()'. Hence we have this
15957 check again in addtion to add_station().
15958 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015959 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015960 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15962 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015963 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15964 __func__, MAC_ADDR_ARRAY(peer), action_code,
15965 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015966 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015967 }
15968 else
15969 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015970 /* maximum reached. tweak to send error code to peer and return
15971 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015972 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15974 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015975 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15976 __func__, MAC_ADDR_ARRAY(peer), status_code,
15977 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015978 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015979 /* fall through to send setup resp with failure status
15980 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015981 }
15982 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015983 else
15984 {
15985 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015986 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015987 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015988 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015990 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15991 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015992 return -EPERM;
15993 }
15994 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015995 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015996
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015998 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015999 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
16000 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016001
Hoonki Leea34dd892013-02-05 22:56:02 -080016002 /*Except teardown responder will not be used so just make 0*/
16003 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016004 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080016005 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016006
16007 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016008 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016009
16010 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
16011 responder = pTdlsPeer->is_responder;
16012 else
Hoonki Leea34dd892013-02-05 22:56:02 -080016013 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053016015 "%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 -070016016 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
16017 dialog_token, status_code, len);
16018 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080016019 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016020 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016021
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016022 /* For explicit trigger of DIS_REQ come out of BMPS for
16023 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070016024 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016025 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
16026 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070016027 {
16028 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
16029 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016031 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016032 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
16033 if (status != VOS_STATUS_SUCCESS) {
16034 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
16035 }
Hoonki Lee14621352013-04-16 17:51:19 -070016036 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016037 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016038 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
16040 }
16041 }
Hoonki Lee14621352013-04-16 17:51:19 -070016042 }
16043
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016044 /* make sure doesn't call send_mgmt() while it is pending */
16045 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
16046 {
16047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016048 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016049 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016050 ret = -EBUSY;
16051 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016052 }
16053
16054 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016055 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
16056
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016057 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
16058 pAdapter->sessionId, peer, action_code, dialog_token,
16059 status_code, peer_capability, (tANI_U8 *)buf, len,
16060 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016061
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016062 if (VOS_STATUS_SUCCESS != status)
16063 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16065 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016066 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016067 ret = -EINVAL;
16068 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016069 }
16070
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016071 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
16072 (SIR_MAC_TDLS_DIS_RSP == action_code))
16073 {
16074 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
16075 * So we no need to wait for tdls_mgmt_comp for sending ack status.
16076 */
16077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16078 "%s: tx done for frm %u", __func__, action_code);
16079 return 0;
16080 }
16081
16082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16083 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
16084 WAIT_TIME_TDLS_MGMT);
16085
Hoonki Leed37cbb32013-04-20 00:31:14 -070016086 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
16087 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
16088
16089 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016090 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070016091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016092 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070016093 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016094 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080016095
16096 if (pHddCtx->isLogpInProgress)
16097 {
16098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16099 "%s: LOGP in Progress. Ignore!!!", __func__);
16100 return -EAGAIN;
16101 }
16102
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016103 ret = -EINVAL;
16104 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016105 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016106 else
16107 {
16108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16109 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
16110 __func__, rc, pAdapter->mgmtTxCompletionStatus);
16111 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016112
Gopichand Nakkala05922802013-03-14 12:23:19 -070016113 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070016114 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016115 ret = max_sta_failed;
16116 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070016117 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016118
Hoonki Leea34dd892013-02-05 22:56:02 -080016119 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
16120 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016121 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16123 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016124 }
16125 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
16126 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016127 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16129 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016130 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016131
16132 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016133
16134tx_failed:
16135 /* add_station will be called before sending TDLS_SETUP_REQ and
16136 * TDLS_SETUP_RSP and as part of add_station driver will enable
16137 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
16138 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
16139 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
16140 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
16141 */
16142
16143 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
16144 (SIR_MAC_TDLS_SETUP_RSP == action_code))
16145 wlan_hdd_tdls_check_bmps(pAdapter);
16146 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016147}
16148
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016149#if TDLS_MGMT_VERSION2
16150static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16151 u8 *peer, u8 action_code, u8 dialog_token,
16152 u16 status_code, u32 peer_capability,
16153 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016154#else /* TDLS_MGMT_VERSION2 */
16155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16156static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16157 struct net_device *dev,
16158 const u8 *peer, u8 action_code,
16159 u8 dialog_token, u16 status_code,
16160 u32 peer_capability, bool initiator,
16161 const u8 *buf, size_t len)
16162#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16163static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16164 struct net_device *dev,
16165 const u8 *peer, u8 action_code,
16166 u8 dialog_token, u16 status_code,
16167 u32 peer_capability, const u8 *buf,
16168 size_t len)
16169#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16170static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16171 struct net_device *dev,
16172 u8 *peer, u8 action_code,
16173 u8 dialog_token,
16174 u16 status_code, u32 peer_capability,
16175 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016176#else
16177static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16178 u8 *peer, u8 action_code, u8 dialog_token,
16179 u16 status_code, const u8 *buf, size_t len)
16180#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016181#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016182{
16183 int ret;
16184
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016185 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016186#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016187 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16188 dialog_token, status_code,
16189 peer_capability, buf, len);
16190#else /* TDLS_MGMT_VERSION2 */
16191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16192 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16193 dialog_token, status_code,
16194 peer_capability, initiator,
16195 buf, len);
16196#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16197 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16198 dialog_token, status_code,
16199 peer_capability, buf, len);
16200#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16201 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16202 dialog_token, status_code,
16203 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016204#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016205 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16206 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016207#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016208#endif
16209 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016210
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016211 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016212}
Atul Mittal115287b2014-07-08 13:26:33 +053016213
16214int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16216 const u8 *peer,
16217#else
Atul Mittal115287b2014-07-08 13:26:33 +053016218 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016219#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016220 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016221 cfg80211_exttdls_callback callback)
16222{
16223
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016224 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016225 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016226 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16228 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16229 __func__, MAC_ADDR_ARRAY(peer));
16230
16231 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16232 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16233
16234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016235 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16236 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16237 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016238 return -ENOTSUPP;
16239 }
16240
16241 /* To cater the requirement of establishing the TDLS link
16242 * irrespective of the data traffic , get an entry of TDLS peer.
16243 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016244 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016245 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16246 if (pTdlsPeer == NULL) {
16247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16248 "%s: peer " MAC_ADDRESS_STR " not existing",
16249 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016250 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016251 return -EINVAL;
16252 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016253 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016254
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016255 /* check FW TDLS Off Channel capability */
16256 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016257 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016258 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016259 {
16260 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16261 pTdlsPeer->peerParams.global_operating_class =
16262 tdls_peer_params->global_operating_class;
16263 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16264 pTdlsPeer->peerParams.min_bandwidth_kbps =
16265 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016266 /* check configured channel is valid, non dfs and
16267 * not current operating channel */
16268 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16269 tdls_peer_params->channel)) &&
16270 (pHddStaCtx) &&
16271 (tdls_peer_params->channel !=
16272 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016273 {
16274 pTdlsPeer->isOffChannelConfigured = TRUE;
16275 }
16276 else
16277 {
16278 pTdlsPeer->isOffChannelConfigured = FALSE;
16279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16280 "%s: Configured Tdls Off Channel is not valid", __func__);
16281
16282 }
16283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016284 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16285 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016286 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016287 pTdlsPeer->isOffChannelConfigured,
16288 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016289 }
16290 else
16291 {
16292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016293 "%s: TDLS off channel FW capability %d, "
16294 "host capab %d or Invalid TDLS Peer Params", __func__,
16295 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16296 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016297 }
16298
Atul Mittal115287b2014-07-08 13:26:33 +053016299 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16300
16301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16302 " %s TDLS Add Force Peer Failed",
16303 __func__);
16304 return -EINVAL;
16305 }
16306 /*EXT TDLS*/
16307
16308 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16310 " %s TDLS set callback Failed",
16311 __func__);
16312 return -EINVAL;
16313 }
16314
16315 return(0);
16316
16317}
16318
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016319int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16321 const u8 *peer
16322#else
16323 u8 *peer
16324#endif
16325)
Atul Mittal115287b2014-07-08 13:26:33 +053016326{
16327
16328 hddTdlsPeer_t *pTdlsPeer;
16329 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16331 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16332 __func__, MAC_ADDR_ARRAY(peer));
16333
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016334 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16336 return -EINVAL;
16337 }
16338
Atul Mittal115287b2014-07-08 13:26:33 +053016339 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16340 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16341
16342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016343 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16344 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16345 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016346 return -ENOTSUPP;
16347 }
16348
16349
16350 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16351
16352 if ( NULL == pTdlsPeer ) {
16353 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016354 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016355 __func__, MAC_ADDR_ARRAY(peer));
16356 return -EINVAL;
16357 }
16358 else {
16359 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16360 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016361 /* if channel switch is configured, reset
16362 the channel for this peer */
16363 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16364 {
16365 pTdlsPeer->peerParams.channel = 0;
16366 pTdlsPeer->isOffChannelConfigured = FALSE;
16367 }
Atul Mittal115287b2014-07-08 13:26:33 +053016368 }
16369
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016370 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016372 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016373 }
Atul Mittal115287b2014-07-08 13:26:33 +053016374
16375 /*EXT TDLS*/
16376
16377 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16378
16379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16380 " %s TDLS set callback Failed",
16381 __func__);
16382 return -EINVAL;
16383 }
16384 return(0);
16385
16386}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016387static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16389 const u8 *peer,
16390#else
16391 u8 *peer,
16392#endif
16393 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016394{
16395 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16396 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016397 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016398 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016400 ENTER();
16401
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016402 if (!pAdapter) {
16403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16404 return -EINVAL;
16405 }
16406
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016407 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16408 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16409 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016410 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016411 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016413 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016414 return -EINVAL;
16415 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016416
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016417 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016418 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016419 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016420 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016421 }
16422
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016423
16424 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016425 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016426 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016428 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16429 "Cannot process TDLS commands",
16430 pHddCtx->cfg_ini->fEnableTDLSSupport,
16431 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016432 return -ENOTSUPP;
16433 }
16434
16435 switch (oper) {
16436 case NL80211_TDLS_ENABLE_LINK:
16437 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016438 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016439 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016440 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016441 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016442 tANI_U16 numCurrTdlsPeers = 0;
16443 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016444 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016445
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16447 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16448 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016449 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016450 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016451 if ( NULL == pTdlsPeer ) {
16452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16453 " (oper %d) not exsting. ignored",
16454 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16455 return -EINVAL;
16456 }
16457
16458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16459 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16460 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16461 "NL80211_TDLS_ENABLE_LINK");
16462
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016463 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16464 {
16465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16466 MAC_ADDRESS_STR " failed",
16467 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16468 return -EINVAL;
16469 }
16470
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016471 /* before starting tdls connection, set tdls
16472 * off channel established status to default value */
16473 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016474 /* TDLS Off Channel, Disable tdls channel switch,
16475 when there are more than one tdls link */
16476 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016477 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016478 {
16479 /* get connected peer and send disable tdls off chan */
16480 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016481 if ((connPeer) &&
16482 (connPeer->isOffChannelSupported == TRUE) &&
16483 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016484 {
16485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16486 "%s: More then one peer connected, Disable "
16487 "TDLS channel switch", __func__);
16488
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016489 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016490 ret = sme_SendTdlsChanSwitchReq(
16491 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016492 pAdapter->sessionId,
16493 connPeer->peerMac,
16494 connPeer->peerParams.channel,
16495 TDLS_OFF_CHANNEL_BW_OFFSET,
16496 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016497 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016498 hddLog(VOS_TRACE_LEVEL_ERROR,
16499 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016500 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016501 }
16502 else
16503 {
16504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16505 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016506 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016507 "isOffChannelConfigured %d",
16508 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016509 (connPeer ? (connPeer->isOffChannelSupported)
16510 : -1),
16511 (connPeer ? (connPeer->isOffChannelConfigured)
16512 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016513 }
16514 }
16515
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016516 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016517 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016518 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016519
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016520 if (0 != wlan_hdd_tdls_get_link_establish_params(
16521 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016523 return -EINVAL;
16524 }
16525 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016526
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016527 ret = sme_SendTdlsLinkEstablishParams(
16528 WLAN_HDD_GET_HAL_CTX(pAdapter),
16529 pAdapter->sessionId, peer,
16530 &tdlsLinkEstablishParams);
16531 if (ret != VOS_STATUS_SUCCESS) {
16532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16533 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016534 /* Send TDLS peer UAPSD capabilities to the firmware and
16535 * register with the TL on after the response for this operation
16536 * is received .
16537 */
16538 ret = wait_for_completion_interruptible_timeout(
16539 &pAdapter->tdls_link_establish_req_comp,
16540 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16541 if (ret <= 0)
16542 {
16543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016544 FL("Link Establish Request Failed Status %ld"),
16545 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016546 return -EINVAL;
16547 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016548 }
Atul Mittal115287b2014-07-08 13:26:33 +053016549 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16550 eTDLS_LINK_CONNECTED,
16551 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016552 staDesc.ucSTAId = pTdlsPeer->staId;
16553 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016554 ret = WLANTL_UpdateTdlsSTAClient(
16555 pHddCtx->pvosContext,
16556 &staDesc);
16557 if (ret != VOS_STATUS_SUCCESS) {
16558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16559 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016560
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016561 /* Mark TDLS client Authenticated .*/
16562 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16563 pTdlsPeer->staId,
16564 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016565 if (VOS_STATUS_SUCCESS == status)
16566 {
Hoonki Lee14621352013-04-16 17:51:19 -070016567 if (pTdlsPeer->is_responder == 0)
16568 {
16569 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016570 tdlsConnInfo_t *tdlsInfo;
16571
16572 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16573
16574 /* Initialize initiator wait callback */
16575 vos_timer_init(
16576 &pTdlsPeer->initiatorWaitTimeoutTimer,
16577 VOS_TIMER_TYPE_SW,
16578 wlan_hdd_tdls_initiator_wait_cb,
16579 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016580
16581 wlan_hdd_tdls_timer_restart(pAdapter,
16582 &pTdlsPeer->initiatorWaitTimeoutTimer,
16583 WAIT_TIME_TDLS_INITIATOR);
16584 /* suspend initiator TX until it receives direct packet from the
16585 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016586 ret = WLANTL_SuspendDataTx(
16587 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16588 &staId, NULL);
16589 if (ret != VOS_STATUS_SUCCESS) {
16590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16591 }
Hoonki Lee14621352013-04-16 17:51:19 -070016592 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016593
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016594 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016595 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016596 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016597 suppChannelLen =
16598 tdlsLinkEstablishParams.supportedChannelsLen;
16599
16600 if ((suppChannelLen > 0) &&
16601 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16602 {
16603 tANI_U8 suppPeerChannel = 0;
16604 int i = 0;
16605 for (i = 0U; i < suppChannelLen; i++)
16606 {
16607 suppPeerChannel =
16608 tdlsLinkEstablishParams.supportedChannels[i];
16609
16610 pTdlsPeer->isOffChannelSupported = FALSE;
16611 if (suppPeerChannel ==
16612 pTdlsPeer->peerParams.channel)
16613 {
16614 pTdlsPeer->isOffChannelSupported = TRUE;
16615 break;
16616 }
16617 }
16618 }
16619 else
16620 {
16621 pTdlsPeer->isOffChannelSupported = FALSE;
16622 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016623 }
16624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16625 "%s: TDLS channel switch request for channel "
16626 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016627 "%d isOffChannelSupported %d", __func__,
16628 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016629 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016630 suppChannelLen,
16631 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016632
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016633 /* TDLS Off Channel, Enable tdls channel switch,
16634 when their is only one tdls link and it supports */
16635 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16636 if ((numCurrTdlsPeers == 1) &&
16637 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16638 (TRUE == pTdlsPeer->isOffChannelConfigured))
16639 {
16640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16641 "%s: Send TDLS channel switch request for channel %d",
16642 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016643
16644 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016645 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16646 pAdapter->sessionId,
16647 pTdlsPeer->peerMac,
16648 pTdlsPeer->peerParams.channel,
16649 TDLS_OFF_CHANNEL_BW_OFFSET,
16650 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016651 if (ret != VOS_STATUS_SUCCESS) {
16652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16653 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016654 }
16655 else
16656 {
16657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16658 "%s: TDLS channel switch request not sent"
16659 " numCurrTdlsPeers %d "
16660 "isOffChannelSupported %d "
16661 "isOffChannelConfigured %d",
16662 __func__, numCurrTdlsPeers,
16663 pTdlsPeer->isOffChannelSupported,
16664 pTdlsPeer->isOffChannelConfigured);
16665 }
16666
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016667 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016668 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016669
16670 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016671 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16672 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016673 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016674 int ac;
16675 uint8 ucAc[4] = { WLANTL_AC_VO,
16676 WLANTL_AC_VI,
16677 WLANTL_AC_BK,
16678 WLANTL_AC_BE };
16679 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16680 for(ac=0; ac < 4; ac++)
16681 {
16682 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16683 pTdlsPeer->staId, ucAc[ac],
16684 tlTid[ac], tlTid[ac], 0, 0,
16685 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016686 if (status != VOS_STATUS_SUCCESS) {
16687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16688 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016689 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016690 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016691 }
16692
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016693 }
16694 break;
16695 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016696 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016697 tANI_U16 numCurrTdlsPeers = 0;
16698 hddTdlsPeer_t *connPeer = NULL;
16699
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16701 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16702 __func__, MAC_ADDR_ARRAY(peer));
16703
Sunil Dutt41de4e22013-11-14 18:09:02 +053016704 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16705
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016706
Sunil Dutt41de4e22013-11-14 18:09:02 +053016707 if ( NULL == pTdlsPeer ) {
16708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16709 " (oper %d) not exsting. ignored",
16710 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16711 return -EINVAL;
16712 }
16713
16714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16715 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16716 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16717 "NL80211_TDLS_DISABLE_LINK");
16718
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016719 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016720 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016721 long status;
16722
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016723 /* set tdls off channel status to false for this peer */
16724 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016725 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16726 eTDLS_LINK_TEARING,
16727 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16728 eTDLS_LINK_UNSPECIFIED:
16729 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016730 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16731
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016732 status = sme_DeleteTdlsPeerSta(
16733 WLAN_HDD_GET_HAL_CTX(pAdapter),
16734 pAdapter->sessionId, peer );
16735 if (status != VOS_STATUS_SUCCESS) {
16736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16737 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016738
16739 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16740 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016741 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016742 eTDLS_LINK_IDLE,
16743 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016744 if (status <= 0)
16745 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16747 "%s: Del station failed status %ld",
16748 __func__, status);
16749 return -EPERM;
16750 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016751
16752 /* TDLS Off Channel, Enable tdls channel switch,
16753 when their is only one tdls link and it supports */
16754 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16755 if (numCurrTdlsPeers == 1)
16756 {
16757 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16758 if ((connPeer) &&
16759 (connPeer->isOffChannelSupported == TRUE) &&
16760 (connPeer->isOffChannelConfigured == TRUE))
16761 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016762 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016763 status = sme_SendTdlsChanSwitchReq(
16764 WLAN_HDD_GET_HAL_CTX(pAdapter),
16765 pAdapter->sessionId,
16766 connPeer->peerMac,
16767 connPeer->peerParams.channel,
16768 TDLS_OFF_CHANNEL_BW_OFFSET,
16769 TDLS_CHANNEL_SWITCH_ENABLE);
16770 if (status != VOS_STATUS_SUCCESS) {
16771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16772 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016773 }
16774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16775 "%s: TDLS channel switch "
16776 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016777 "isOffChannelConfigured %d "
16778 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016779 __func__,
16780 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016781 (connPeer ? connPeer->isOffChannelConfigured : -1),
16782 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016783 }
16784 else
16785 {
16786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16787 "%s: TDLS channel switch request not sent "
16788 "numCurrTdlsPeers %d ",
16789 __func__, numCurrTdlsPeers);
16790 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016791 }
16792 else
16793 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16795 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016796 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016797 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016798 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016799 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016800 {
Atul Mittal115287b2014-07-08 13:26:33 +053016801 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016802
Atul Mittal115287b2014-07-08 13:26:33 +053016803 if (0 != status)
16804 {
16805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016806 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016807 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016808 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016809 break;
16810 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016811 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016812 {
Atul Mittal115287b2014-07-08 13:26:33 +053016813 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16814 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016815 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016816 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016817
Atul Mittal115287b2014-07-08 13:26:33 +053016818 if (0 != status)
16819 {
16820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016821 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016822 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016823 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016824 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016825 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016826 case NL80211_TDLS_DISCOVERY_REQ:
16827 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016829 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016830 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016831 return -ENOTSUPP;
16832 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16834 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016835 return -ENOTSUPP;
16836 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016837
16838 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016839 return 0;
16840}
Chilam NG571c65a2013-01-19 12:27:36 +053016841
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016842static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016843#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16844 const u8 *peer,
16845#else
16846 u8 *peer,
16847#endif
16848 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016849{
16850 int ret;
16851
16852 vos_ssr_protect(__func__);
16853 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16854 vos_ssr_unprotect(__func__);
16855
16856 return ret;
16857}
16858
Chilam NG571c65a2013-01-19 12:27:36 +053016859int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16860 struct net_device *dev, u8 *peer)
16861{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016862 hddLog(VOS_TRACE_LEVEL_INFO,
16863 "tdls send discover req: "MAC_ADDRESS_STR,
16864 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016865
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016866#if TDLS_MGMT_VERSION2
16867 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16868 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16869#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16871 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16872 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16873#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16874 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16875 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16876#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16877 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16878 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16879#else
Chilam NG571c65a2013-01-19 12:27:36 +053016880 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16881 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016882#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016883#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016884}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016885#endif
16886
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016887#ifdef WLAN_FEATURE_GTK_OFFLOAD
16888/*
16889 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16890 * Callback rountine called upon receiving response for
16891 * get offload info
16892 */
16893void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16894 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16895{
16896
16897 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016898 tANI_U8 tempReplayCounter[8];
16899 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016900
16901 ENTER();
16902
16903 if (NULL == pAdapter)
16904 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016906 "%s: HDD adapter is Null", __func__);
16907 return ;
16908 }
16909
16910 if (NULL == pGtkOffloadGetInfoRsp)
16911 {
16912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16913 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16914 return ;
16915 }
16916
16917 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16918 {
16919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16920 "%s: wlan Failed to get replay counter value",
16921 __func__);
16922 return ;
16923 }
16924
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016925 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16926 /* Update replay counter */
16927 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16928 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16929
16930 {
16931 /* changing from little to big endian since supplicant
16932 * works on big endian format
16933 */
16934 int i;
16935 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16936
16937 for (i = 0; i < 8; i++)
16938 {
16939 tempReplayCounter[7-i] = (tANI_U8)p[i];
16940 }
16941 }
16942
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016943 /* Update replay counter to NL */
16944 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016945 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016946}
16947
16948/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016949 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016950 * This function is used to offload GTK rekeying job to the firmware.
16951 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016952int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016953 struct cfg80211_gtk_rekey_data *data)
16954{
16955 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16956 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16957 hdd_station_ctx_t *pHddStaCtx;
16958 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016959 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016960 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016961 eHalStatus status = eHAL_STATUS_FAILURE;
16962
16963 ENTER();
16964
16965 if (NULL == pAdapter)
16966 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016968 "%s: HDD adapter is Null", __func__);
16969 return -ENODEV;
16970 }
16971
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016972 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16973 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16974 pAdapter->sessionId, pAdapter->device_mode));
16975
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016976 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016977 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016978 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016979 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016980 }
16981
16982 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16983 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16984 if (NULL == hHal)
16985 {
16986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16987 "%s: HAL context is Null!!!", __func__);
16988 return -EAGAIN;
16989 }
16990
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016991 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16992 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16993 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16994 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016995 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016996 {
16997 /* changing from big to little endian since driver
16998 * works on little endian format
16999 */
17000 tANI_U8 *p =
17001 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
17002 int i;
17003
17004 for (i = 0; i < 8; i++)
17005 {
17006 p[7-i] = data->replay_ctr[i];
17007 }
17008 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017009
17010 if (TRUE == pHddCtx->hdd_wlan_suspended)
17011 {
17012 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017013 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
17014 sizeof (tSirGtkOffloadParams));
17015 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017016 pAdapter->sessionId);
17017
17018 if (eHAL_STATUS_SUCCESS != status)
17019 {
17020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17021 "%s: sme_SetGTKOffload failed, returned %d",
17022 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017023
17024 /* Need to clear any trace of key value in the memory.
17025 * Thus zero out the memory even though it is local
17026 * variable.
17027 */
17028 vos_mem_zero(&hddGtkOffloadReqParams,
17029 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017030 return status;
17031 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17033 "%s: sme_SetGTKOffload successfull", __func__);
17034 }
17035 else
17036 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17038 "%s: wlan not suspended GTKOffload request is stored",
17039 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017040 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017041
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017042 /* Need to clear any trace of key value in the memory.
17043 * Thus zero out the memory even though it is local
17044 * variable.
17045 */
17046 vos_mem_zero(&hddGtkOffloadReqParams,
17047 sizeof(hddGtkOffloadReqParams));
17048
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017049 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017050 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017051}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017052
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017053int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
17054 struct cfg80211_gtk_rekey_data *data)
17055{
17056 int ret;
17057
17058 vos_ssr_protect(__func__);
17059 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
17060 vos_ssr_unprotect(__func__);
17061
17062 return ret;
17063}
17064#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017065/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017066 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017067 * This function is used to set access control policy
17068 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017069static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17070 struct net_device *dev,
17071 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017072{
17073 int i;
17074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17075 hdd_hostapd_state_t *pHostapdState;
17076 tsap_Config_t *pConfig;
17077 v_CONTEXT_t pVosContext = NULL;
17078 hdd_context_t *pHddCtx;
17079 int status;
17080
17081 ENTER();
17082
17083 if (NULL == pAdapter)
17084 {
17085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17086 "%s: HDD adapter is Null", __func__);
17087 return -ENODEV;
17088 }
17089
17090 if (NULL == params)
17091 {
17092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17093 "%s: params is Null", __func__);
17094 return -EINVAL;
17095 }
17096
17097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17098 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017099 if (0 != status)
17100 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017101 return status;
17102 }
17103
17104 pVosContext = pHddCtx->pvosContext;
17105 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
17106
17107 if (NULL == pHostapdState)
17108 {
17109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17110 "%s: pHostapdState is Null", __func__);
17111 return -EINVAL;
17112 }
17113
17114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
17115 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17117 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
17118 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017119
17120 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
17121 {
17122 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
17123
17124 /* default value */
17125 pConfig->num_accept_mac = 0;
17126 pConfig->num_deny_mac = 0;
17127
17128 /**
17129 * access control policy
17130 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
17131 * listed in hostapd.deny file.
17132 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
17133 * listed in hostapd.accept file.
17134 */
17135 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
17136 {
17137 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
17138 }
17139 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
17140 {
17141 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
17142 }
17143 else
17144 {
17145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17146 "%s:Acl Policy : %d is not supported",
17147 __func__, params->acl_policy);
17148 return -ENOTSUPP;
17149 }
17150
17151 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
17152 {
17153 pConfig->num_accept_mac = params->n_acl_entries;
17154 for (i = 0; i < params->n_acl_entries; i++)
17155 {
17156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17157 "** Add ACL MAC entry %i in WhiletList :"
17158 MAC_ADDRESS_STR, i,
17159 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17160
17161 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17162 sizeof(qcmacaddr));
17163 }
17164 }
17165 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17166 {
17167 pConfig->num_deny_mac = params->n_acl_entries;
17168 for (i = 0; i < params->n_acl_entries; i++)
17169 {
17170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17171 "** Add ACL MAC entry %i in BlackList :"
17172 MAC_ADDRESS_STR, i,
17173 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17174
17175 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17176 sizeof(qcmacaddr));
17177 }
17178 }
17179
17180 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17181 {
17182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17183 "%s: SAP Set Mac Acl fail", __func__);
17184 return -EINVAL;
17185 }
17186 }
17187 else
17188 {
17189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017190 "%s: Invalid device_mode = %s (%d)",
17191 __func__, hdd_device_modetoString(pAdapter->device_mode),
17192 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017193 return -EINVAL;
17194 }
17195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017196 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017197 return 0;
17198}
17199
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017200static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17201 struct net_device *dev,
17202 const struct cfg80211_acl_data *params)
17203{
17204 int ret;
17205 vos_ssr_protect(__func__);
17206 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17207 vos_ssr_unprotect(__func__);
17208
17209 return ret;
17210}
17211
Leo Chang9056f462013-08-01 19:21:11 -070017212#ifdef WLAN_NL80211_TESTMODE
17213#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017214void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017215(
17216 void *pAdapter,
17217 void *indCont
17218)
17219{
Leo Changd9df8aa2013-09-26 13:32:26 -070017220 tSirLPHBInd *lphbInd;
17221 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017222 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017223
17224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017225 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017226
c_hpothu73f35e62014-04-18 13:40:08 +053017227 if (pAdapter == NULL)
17228 {
17229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17230 "%s: pAdapter is NULL\n",__func__);
17231 return;
17232 }
17233
Leo Chang9056f462013-08-01 19:21:11 -070017234 if (NULL == indCont)
17235 {
17236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017237 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017238 return;
17239 }
17240
c_hpothu73f35e62014-04-18 13:40:08 +053017241 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017242 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017243 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017244 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017245 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017246 GFP_ATOMIC);
17247 if (!skb)
17248 {
17249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17250 "LPHB timeout, NL buffer alloc fail");
17251 return;
17252 }
17253
Leo Changac3ba772013-10-07 09:47:04 -070017254 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017255 {
17256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17257 "WLAN_HDD_TM_ATTR_CMD put fail");
17258 goto nla_put_failure;
17259 }
Leo Changac3ba772013-10-07 09:47:04 -070017260 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017261 {
17262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17263 "WLAN_HDD_TM_ATTR_TYPE put fail");
17264 goto nla_put_failure;
17265 }
Leo Changac3ba772013-10-07 09:47:04 -070017266 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017267 sizeof(tSirLPHBInd), lphbInd))
17268 {
17269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17270 "WLAN_HDD_TM_ATTR_DATA put fail");
17271 goto nla_put_failure;
17272 }
Leo Chang9056f462013-08-01 19:21:11 -070017273 cfg80211_testmode_event(skb, GFP_ATOMIC);
17274 return;
17275
17276nla_put_failure:
17277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17278 "NLA Put fail");
17279 kfree_skb(skb);
17280
17281 return;
17282}
17283#endif /* FEATURE_WLAN_LPHB */
17284
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017285static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017286{
17287 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17288 int err = 0;
17289#ifdef FEATURE_WLAN_LPHB
17290 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017291 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017292
17293 ENTER();
17294
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017295 err = wlan_hdd_validate_context(pHddCtx);
17296 if (0 != err)
17297 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017298 return err;
17299 }
Leo Chang9056f462013-08-01 19:21:11 -070017300#endif /* FEATURE_WLAN_LPHB */
17301
17302 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17303 if (err)
17304 {
17305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17306 "%s Testmode INV ATTR", __func__);
17307 return err;
17308 }
17309
17310 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17311 {
17312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17313 "%s Testmode INV CMD", __func__);
17314 return -EINVAL;
17315 }
17316
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017317 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17318 TRACE_CODE_HDD_CFG80211_TESTMODE,
17319 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017320 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17321 {
17322#ifdef FEATURE_WLAN_LPHB
17323 /* Low Power Heartbeat configuration request */
17324 case WLAN_HDD_TM_CMD_WLAN_HB:
17325 {
17326 int buf_len;
17327 void *buf;
17328 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017329 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017330
17331 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17332 {
17333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17334 "%s Testmode INV DATA", __func__);
17335 return -EINVAL;
17336 }
17337
17338 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17339 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017340
17341 hb_params_temp =(tSirLPHBReq *)buf;
17342 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17343 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17344 return -EINVAL;
17345
Leo Chang9056f462013-08-01 19:21:11 -070017346 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17347 if (NULL == hb_params)
17348 {
17349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17350 "%s Request Buffer Alloc Fail", __func__);
17351 return -EINVAL;
17352 }
17353
17354 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017355 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17356 hb_params,
17357 wlan_hdd_cfg80211_lphb_ind_handler);
17358 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017359 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17361 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017362 vos_mem_free(hb_params);
17363 }
Leo Chang9056f462013-08-01 19:21:11 -070017364 return 0;
17365 }
17366#endif /* FEATURE_WLAN_LPHB */
17367 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17369 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017370 return -EOPNOTSUPP;
17371 }
17372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017373 EXIT();
17374 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017375}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017376
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017377static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17378#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17379 struct wireless_dev *wdev,
17380#endif
17381 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017382{
17383 int ret;
17384
17385 vos_ssr_protect(__func__);
17386 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17387 vos_ssr_unprotect(__func__);
17388
17389 return ret;
17390}
Leo Chang9056f462013-08-01 19:21:11 -070017391#endif /* CONFIG_NL80211_TESTMODE */
17392
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017393static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017394 struct net_device *dev,
17395 int idx, struct survey_info *survey)
17396{
17397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17398 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017399 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017400 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017401 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017402 v_S7_t snr,rssi;
17403 int status, i, j, filled = 0;
17404
17405 ENTER();
17406
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017407 if (NULL == pAdapter)
17408 {
17409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17410 "%s: HDD adapter is Null", __func__);
17411 return -ENODEV;
17412 }
17413
17414 if (NULL == wiphy)
17415 {
17416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17417 "%s: wiphy is Null", __func__);
17418 return -ENODEV;
17419 }
17420
17421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17422 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017423 if (0 != status)
17424 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017425 return status;
17426 }
17427
Mihir Sheted9072e02013-08-21 17:02:29 +053017428 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17429
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017430 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017431 0 != pAdapter->survey_idx ||
17432 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017433 {
17434 /* The survey dump ops when implemented completely is expected to
17435 * return a survey of all channels and the ops is called by the
17436 * kernel with incremental values of the argument 'idx' till it
17437 * returns -ENONET. But we can only support the survey for the
17438 * operating channel for now. survey_idx is used to track
17439 * that the ops is called only once and then return -ENONET for
17440 * the next iteration
17441 */
17442 pAdapter->survey_idx = 0;
17443 return -ENONET;
17444 }
17445
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017446 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17447 {
17448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17449 "%s: Roaming in progress, hence return ", __func__);
17450 return -ENONET;
17451 }
17452
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017453 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17454
17455 wlan_hdd_get_snr(pAdapter, &snr);
17456 wlan_hdd_get_rssi(pAdapter, &rssi);
17457
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17459 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17460 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017461 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17462 hdd_wlan_get_freq(channel, &freq);
17463
17464
17465 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17466 {
17467 if (NULL == wiphy->bands[i])
17468 {
17469 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17470 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17471 continue;
17472 }
17473
17474 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17475 {
17476 struct ieee80211_supported_band *band = wiphy->bands[i];
17477
17478 if (band->channels[j].center_freq == (v_U16_t)freq)
17479 {
17480 survey->channel = &band->channels[j];
17481 /* The Rx BDs contain SNR values in dB for the received frames
17482 * while the supplicant expects noise. So we calculate and
17483 * return the value of noise (dBm)
17484 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17485 */
17486 survey->noise = rssi - snr;
17487 survey->filled = SURVEY_INFO_NOISE_DBM;
17488 filled = 1;
17489 }
17490 }
17491 }
17492
17493 if (filled)
17494 pAdapter->survey_idx = 1;
17495 else
17496 {
17497 pAdapter->survey_idx = 0;
17498 return -ENONET;
17499 }
17500
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017501 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017502 return 0;
17503}
17504
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017505static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17506 struct net_device *dev,
17507 int idx, struct survey_info *survey)
17508{
17509 int ret;
17510
17511 vos_ssr_protect(__func__);
17512 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17513 vos_ssr_unprotect(__func__);
17514
17515 return ret;
17516}
17517
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017518/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017519 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017520 * this is called when cfg80211 driver resume
17521 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17522 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017523int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017524{
17525 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17526 hdd_adapter_t *pAdapter;
17527 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17528 VOS_STATUS status = VOS_STATUS_SUCCESS;
17529
17530 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017531
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017532 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017533 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017534 return 0;
17535 }
17536
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017537 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17538 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017539 spin_lock(&pHddCtx->schedScan_lock);
17540 pHddCtx->isWiphySuspended = FALSE;
17541 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17542 {
17543 spin_unlock(&pHddCtx->schedScan_lock);
17544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17545 "%s: Return resume is not due to PNO indication", __func__);
17546 return 0;
17547 }
17548 // Reset flag to avoid updatating cfg80211 data old results again
17549 pHddCtx->isSchedScanUpdatePending = FALSE;
17550 spin_unlock(&pHddCtx->schedScan_lock);
17551
17552 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17553
17554 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17555 {
17556 pAdapter = pAdapterNode->pAdapter;
17557 if ( (NULL != pAdapter) &&
17558 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17559 {
17560 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017561 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17563 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017564 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017565 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017566 {
17567 /* Acquire wakelock to handle the case where APP's tries to
17568 * suspend immediately after updating the scan results. Whis
17569 * results in app's is in suspended state and not able to
17570 * process the connect request to AP
17571 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017572 hdd_prevent_suspend_timeout(2000,
17573 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017574 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017575 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017576
17577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17578 "%s : cfg80211 scan result database updated", __func__);
17579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017580 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017581 return 0;
17582
17583 }
17584 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17585 pAdapterNode = pNext;
17586 }
17587
17588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17589 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017590 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017591 return 0;
17592}
17593
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017594int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17595{
17596 int ret;
17597
17598 vos_ssr_protect(__func__);
17599 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17600 vos_ssr_unprotect(__func__);
17601
17602 return ret;
17603}
17604
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017605/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017606 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017607 * this is called when cfg80211 driver suspends
17608 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017609int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017610 struct cfg80211_wowlan *wow)
17611{
17612 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017613 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017614
17615 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017616
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017617 ret = wlan_hdd_validate_context(pHddCtx);
17618 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017619 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017620 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017621 }
17622
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017623
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017624 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17625 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17626 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017627 pHddCtx->isWiphySuspended = TRUE;
17628
17629 EXIT();
17630
17631 return 0;
17632}
17633
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017634int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17635 struct cfg80211_wowlan *wow)
17636{
17637 int ret;
17638
17639 vos_ssr_protect(__func__);
17640 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17641 vos_ssr_unprotect(__func__);
17642
17643 return ret;
17644}
Jeff Johnson295189b2012-06-20 16:38:30 -070017645/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017646static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017647{
17648 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17649 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17650 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17651 .change_station = wlan_hdd_change_station,
17652#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17653 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17654 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17655 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017656#else
17657 .start_ap = wlan_hdd_cfg80211_start_ap,
17658 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17659 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017660#endif
17661 .change_bss = wlan_hdd_cfg80211_change_bss,
17662 .add_key = wlan_hdd_cfg80211_add_key,
17663 .get_key = wlan_hdd_cfg80211_get_key,
17664 .del_key = wlan_hdd_cfg80211_del_key,
17665 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017666#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017667 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017668#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017669 .scan = wlan_hdd_cfg80211_scan,
17670 .connect = wlan_hdd_cfg80211_connect,
17671 .disconnect = wlan_hdd_cfg80211_disconnect,
17672 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17673 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17674 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17675 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17676 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017677 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17678 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017679 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17681 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17682 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17683 .set_txq_params = wlan_hdd_set_txq_params,
17684#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017685 .get_station = wlan_hdd_cfg80211_get_station,
17686 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17687 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017688 .add_station = wlan_hdd_cfg80211_add_station,
17689#ifdef FEATURE_WLAN_LFR
17690 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17691 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17692 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17693#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017694#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17695 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17696#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017697#ifdef FEATURE_WLAN_TDLS
17698 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17699 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17700#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017701#ifdef WLAN_FEATURE_GTK_OFFLOAD
17702 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17703#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017704#ifdef FEATURE_WLAN_SCAN_PNO
17705 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17706 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17707#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017708 .resume = wlan_hdd_cfg80211_resume_wlan,
17709 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017710 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017711#ifdef WLAN_NL80211_TESTMODE
17712 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17713#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017714 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017715};
17716